/*******************************************************************************
 * Copyright (c) 2000, 2006 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
 *******************************************************************************/
package org.eclipse.ui.externaltools.internal.launchConfigurations;


import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.RefreshTab;
import org.eclipse.debug.ui.StringVariableSelectionDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
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.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.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.IWorkingSetEditWizard;
import org.eclipse.ui.externaltools.internal.model.BuilderUtils;
import org.eclipse.ui.externaltools.internal.model.ExternalToolsPlugin;
import org.eclipse.ui.externaltools.internal.model.IExternalToolConstants;
import org.eclipse.ui.externaltools.internal.model.IExternalToolsHelpContextIds;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceSorter;

public class ExternalToolsBuilderTab extends AbstractLaunchConfigurationTab {

	protected Button afterClean;
	protected Button fDuringClean;
	protected Button autoBuildButton;
	protected Button manualBuild;
	protected Button workingSetButton;
	protected Button specifyResources;
	protected Button fLaunchInBackgroundButton;
	protected IWorkingSet workingSet; 
	protected ILaunchConfiguration fConfiguration;
	
    private boolean fCreateBuildScheduleComponent= true;
    
    // Console Output widgets
    private Button fConsoleOutput;
    private Button fFileOutput;
    private Button fFileBrowse;
    private Text fFileText;
    private Button fVariables;
    private Button fAppend;
    private Button fWorkspaceBrowse;
    
    public ExternalToolsBuilderTab() {
    }
    
    public ExternalToolsBuilderTab(boolean createBuildScheduleComponent) {
        fCreateBuildScheduleComponent= createBuildScheduleComponent;
    }
    
	protected SelectionListener selectionListener= new SelectionAdapter() {
		/* (non-Javadoc)
		 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
		 */
		public void widgetSelected(SelectionEvent e) {
			boolean enabled= !fCreateBuildScheduleComponent || autoBuildButton.getSelection() || manualBuild.getSelection();
			workingSetButton.setEnabled(enabled);
			specifyResources.setEnabled(enabled && workingSetButton.getSelection());
			updateLaunchConfigurationDialog();
		}
	};

	public void createControl(Composite parent) {
		Composite mainComposite = new Composite(parent, SWT.NONE);
		setControl(mainComposite);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IExternalToolsHelpContextIds.EXTERNAL_TOOLS_LAUNCH_CONFIGURATION_DIALOG_BUILDER_TAB);
		
		GridLayout layout = new GridLayout();
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 2;
		layout.numColumns = 2;
		layout.makeColumnsEqualWidth = false;
		mainComposite.setLayout(layout);
		mainComposite.setLayoutData(gridData);
		mainComposite.setFont(parent.getFont());
        createOutputCaptureComponent(mainComposite);
		createLaunchInBackgroundComposite(mainComposite);
		createBuildScheduleComponent(mainComposite);
	}
	
	/**
	 * Creates the controls needed to edit the launch in background
	 * attribute of an external tool
	 *
	 * @param parent the composite to create the controls in
	 */
	protected void createLaunchInBackgroundComposite(Composite parent) {
		fLaunchInBackgroundButton = createCheckButton(parent, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_14);
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		data.horizontalSpan = 2;
		fLaunchInBackgroundButton.setLayoutData(data);
		fLaunchInBackgroundButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateLaunchConfigurationDialog();
			}
		});
	}
	
	protected void createBuildScheduleComponent(Composite parent) {
        if (fCreateBuildScheduleComponent) {
    		Label label= new Label(parent, SWT.NONE);
    		label.setText(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_Run_this_builder_for__1);
    		label.setFont(parent.getFont());
    		afterClean= createButton(parent, selectionListener, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab__Full_builds_2, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_Full, 2);
    		manualBuild= createButton(parent, selectionListener, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab__Incremental_builds_4, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_Inc, 2);
    		autoBuildButton= createButton(parent, selectionListener, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab__Auto_builds__Not_recommended__6, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_Auto, 2);  
    		fDuringClean= createButton(parent, selectionListener, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_0, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_1, 2);
    		
    		createVerticalSpacer(parent, 2);
        }
		
		workingSetButton= createButton(parent, selectionListener, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_workingSet_label, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_workingSet_tooltip, 1);
		specifyResources= createPushButton(parent, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_13, null);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		specifyResources.setLayoutData(gd);
		specifyResources.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				selectResources();
			}
		});
        Label label= new Label(parent, SWT.NONE);
        label.setText(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_2);
        label.setFont(parent.getFont());
	}
    
    private void createOutputCaptureComponent(Composite parent) {
        Group group = new Group(parent, SWT.NONE);
        group.setText(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_17); 
        GridData gd = new GridData(SWT.FILL, SWT.NONE, true, false);
        gd.horizontalSpan = 2;
        group.setLayoutData(gd);
        GridLayout layout = new GridLayout(5, false);
        group.setLayout(layout);
        group.setFont(parent.getFont());
        
        fConsoleOutput = createCheckButton(group, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_18); 
        gd = new GridData(SWT.BEGINNING, SWT.NORMAL, true, false);
        gd.horizontalSpan = 5;
        fConsoleOutput.setLayoutData(gd);
        
        fConsoleOutput.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        
        fFileOutput = createCheckButton(group, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_19); 
        fFileOutput.setLayoutData(new GridData(SWT.BEGINNING, SWT.NORMAL, false, false));
        
        fFileText = new Text(group, SWT.SINGLE | SWT.BORDER);
        gd = new GridData(SWT.FILL, SWT.NORMAL, true, false);
        gd.horizontalSpan = 4;
        fFileText.setLayoutData(gd);
        fFileText.setFont(parent.getFont());
        
        Label spacer = new Label(group,SWT.NONE);
        gd = new GridData(SWT.FILL, SWT.NORMAL, true, false);
        gd.horizontalSpan=2;
        spacer.setLayoutData(gd);
        fWorkspaceBrowse = createPushButton(group, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_20, null); 
        fFileBrowse = createPushButton(group, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_21, null); 
        fVariables = createPushButton(group, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_22, null); 

        spacer = new Label(group,SWT.NONE);
        spacer.setLayoutData(new GridData(SWT.FILL, SWT.NORMAL, false, false));
        fAppend = createCheckButton(group, ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_23); 
        gd = new GridData(SWT.LEFT, SWT.TOP, true, false);
        gd.horizontalSpan = 4;
        fAppend.setLayoutData(gd);
        
        fFileOutput.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                boolean enabled = fFileOutput.getSelection();
                fFileText.setEnabled(enabled);
                fFileBrowse.setEnabled(enabled);
                fWorkspaceBrowse.setEnabled(enabled);
                fVariables.setEnabled(enabled);
                fAppend.setEnabled(enabled);
                updateLaunchConfigurationDialog();
            }
        });
        
        fAppend.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        
        fWorkspaceBrowse.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
                dialog.setTitle(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_24); 
                dialog.setMessage(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_25); 
                dialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); 
                dialog.setSorter(new ResourceSorter(ResourceSorter.NAME));
                int buttonId = dialog.open();
                if (buttonId == IDialogConstants.OK_ID) {
                    IResource resource = (IResource) dialog.getFirstResult();
                    String arg = resource.getFullPath().toString();
                    String fileLoc = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", arg); //$NON-NLS-1$
                    fFileText.setText(fileLoc);
                }
            }
        });
        
        fFileBrowse.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                String filePath = fFileText.getText();
                FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
                
                filePath = dialog.open();
                if (filePath != null) {
                    fFileText.setText(filePath);
                }
            }
        });
        
        fFileText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        
        fVariables.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell());
                dialog.open();
                String variable = dialog.getVariableExpression();
                if (variable != null) {
                    fFileText.insert(variable);
                }
            }
            public void widgetDefaultSelected(SelectionEvent e) {   
            }
        });
    }
	
	/*
	 * Creates a check button in the given composite with the given text
	 */
	protected Button createButton(Composite parent, SelectionListener listener, String text, String tooltipText, int columns) {
		Button button= createCheckButton(parent, text);
		button.setToolTipText(tooltipText);
		button.addSelectionListener(listener);
        GridData gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = columns;
		button.setLayoutData(gd);
		return button;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
		StringBuffer buffer= new StringBuffer(IExternalToolConstants.BUILD_TYPE_FULL);
		buffer.append(',');
		buffer.append(IExternalToolConstants.BUILD_TYPE_INCREMENTAL);
		buffer.append(','); 
		configuration.setAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS, buffer.toString());
		configuration.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, false);
		configuration.setAttribute(IExternalToolConstants.ATTR_TRIGGERS_CONFIGURED, true);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	public void initializeFrom(ILaunchConfiguration configuration) {
		fConfiguration= configuration;
        if (fCreateBuildScheduleComponent) {
            afterClean.setSelection(false);
            manualBuild.setSelection(false);
            autoBuildButton.setSelection(false);
            fDuringClean.setSelection(false);
        }

		String buildKindString= null;
		String buildScope= null;
		try {
			buildKindString= configuration.getAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS, ""); //$NON-NLS-1$
			buildScope= configuration.getAttribute(IExternalToolConstants.ATTR_BUILD_SCOPE, (String)null);
		} catch (CoreException e) {
		}
		
		workingSetButton.setSelection(buildScope != null);
		workingSetButton.setEnabled(buildScope != null);
		
		if (buildScope != null) {
			workingSet = RefreshTab.getWorkingSet(buildScope);
		}
		
        if (fCreateBuildScheduleComponent) {
    		int buildTypes[]= BuilderUtils.buildTypesToArray(buildKindString);
    		for (int i = 0; i < buildTypes.length; i++) {
    			switch (buildTypes[i]) {
    				case IncrementalProjectBuilder.FULL_BUILD:
    					afterClean.setSelection(true);
    					break;
    				case IncrementalProjectBuilder.INCREMENTAL_BUILD:
    					manualBuild.setSelection(true);
    					break;
    				case IncrementalProjectBuilder.AUTO_BUILD:
    					autoBuildButton.setSelection(true);
    					break;
    				case IncrementalProjectBuilder.CLEAN_BUILD:
    					fDuringClean.setSelection(true);
    					break;
    			}
    		}
        }
        
		boolean enabled= true;
		if (fCreateBuildScheduleComponent) {
			enabled= autoBuildButton.getSelection() || manualBuild.getSelection();
		}
		workingSetButton.setEnabled(enabled);
		specifyResources.setEnabled(enabled && workingSetButton.getSelection());
		updateRunInBackground(configuration);
        updateConsoleOutput(configuration);
	}
	
	protected void updateRunInBackground(ILaunchConfiguration configuration) { 
		fLaunchInBackgroundButton.setSelection(isLaunchInBackground(configuration));
	}
    
    private void updateConsoleOutput(ILaunchConfiguration configuration) {
        boolean outputToConsole = true;
        String outputFile = null;
        boolean append = false;
        
        try {
            outputToConsole = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, true);
            outputFile = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String)null);
            append = configuration.getAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, false);
        } catch (CoreException e) {
        }
        
        fConsoleOutput.setSelection(outputToConsole);
        fAppend.setSelection(append);
        boolean haveOutputFile= outputFile != null;
        if (haveOutputFile) {
            fFileText.setText(outputFile);
        }
        fFileOutput.setSelection(haveOutputFile);
        fFileText.setEnabled(haveOutputFile);
        fFileBrowse.setEnabled(haveOutputFile);
        fWorkspaceBrowse.setEnabled(haveOutputFile);
        fVariables.setEnabled(haveOutputFile);
        fAppend.setEnabled(haveOutputFile);
    }
	
	/**
	 * Returns whether the given configuration should be run in the background.
	 * 
	 * @param configuration the configuration
	 * @return whether the configuration is configured to run in the background
	 */
	public static boolean isLaunchInBackground(ILaunchConfiguration configuration) {
		boolean launchInBackground= false;
		try {
			launchInBackground= configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, false);
		} catch (CoreException ce) {
			ExternalToolsPlugin.getDefault().log(ce);
		}
		return launchInBackground;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        if (fCreateBuildScheduleComponent) {
		StringBuffer buffer= new StringBuffer();
    		if (afterClean.getSelection()) {
    			buffer.append(IExternalToolConstants.BUILD_TYPE_FULL).append(',');
    		} 
    		if (manualBuild.getSelection()){
    			buffer.append(IExternalToolConstants.BUILD_TYPE_INCREMENTAL).append(','); 
    		} 
    		if (autoBuildButton.getSelection()) {
    			buffer.append(IExternalToolConstants.BUILD_TYPE_AUTO).append(',');
    		}
    		
    		if (fDuringClean.getSelection()) {
    			buffer.append(IExternalToolConstants.BUILD_TYPE_CLEAN);
    		}
    		configuration.setAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS, buffer.toString());
        }
		if (workingSetButton.getSelection()) {
			String scope = RefreshTab.getRefreshAttribute(workingSet);
			configuration.setAttribute(IExternalToolConstants.ATTR_BUILD_SCOPE, scope);
		} else {
			configuration.setAttribute(IExternalToolConstants.ATTR_BUILD_SCOPE, (String)null);
		}
		configuration.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, fLaunchInBackgroundButton.getSelection());
        
        boolean captureOutput = false;
        if (fConsoleOutput.getSelection()) {
            captureOutput = true;
            configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, (String)null);
        } else {
            configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, false);
        }
        if (fFileOutput.getSelection()) {
            captureOutput = true;
            String file = fFileText.getText();
            configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, file);
            if(fAppend.getSelection()) {
                configuration.setAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, true);
            } else {
                configuration.setAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, (String)null);
            }
        } else {
            configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String)null);
        }
        
        if (!captureOutput) {
            configuration.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, false);
        } else {
            configuration.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, (String)null);
        }
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
	 */
	public String getName() {
		return ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_Build_Options_9;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
	 */
	public Image getImage() {
		return PlatformUI.getWorkbench().getSharedImages().getImage(IDE.SharedImages.IMG_OBJ_PROJECT);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	public boolean isValid(ILaunchConfiguration launchConfig) {
		setErrorMessage(null);
		setMessage(null);
		if (fCreateBuildScheduleComponent) {
		    boolean buildKindSelected= afterClean.getSelection() || manualBuild.getSelection() || autoBuildButton.getSelection() || fDuringClean.getSelection();
    		if (!buildKindSelected) {
    			setErrorMessage(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_buildKindError);
    			return false;
    		}
        }
		if (workingSetButton.getSelection() && (workingSet == null || workingSet.getElements().length == 0)) {
			setErrorMessage(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_16);
            return false;
		}
		
		return validateRedirectFile();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#canSave()
	 */
	public boolean canSave() {
		return isValid(null);
	}

	/**
	 * Prompts the user to select the working set that triggers the build.
	 */
	private void selectResources() {
		IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager();
		
		if (workingSet == null){
			workingSet = workingSetManager.createWorkingSet(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_15, new IAdaptable[0]);
		}
		IWorkingSetEditWizard wizard= workingSetManager.createWorkingSetEditWizard(workingSet);
		WizardDialog dialog = new WizardDialog(ExternalToolsPlugin.getStandardDisplay().getActiveShell(), wizard);
		dialog.create();		
		
		if (dialog.open() == Window.CANCEL) {
			return;
		}
		workingSet = wizard.getSelection();
		updateLaunchConfigurationDialog();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
		// do nothing on activation
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
		// do nothing on deactivation
	}
    
    private boolean validateRedirectFile() {
        if(fFileOutput.getSelection()) {
            int len = fFileText.getText().trim().length();
            if (len == 0) {
                setErrorMessage(ExternalToolsLaunchConfigurationMessages.ExternalToolsBuilderTab_26); 
                return false;
            }
        }
        return true;
    }
}