/*******************************************************************************
* Copyright (c) 2000, 2007 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
*
*******************************************************************************/
package org.eclipse.dltk.tcl.ui.tests.wizardapi;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IScriptLanguageProvider;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.internal.ui.wizards.NewWizardMessages;
import org.eclipse.dltk.tcl.core.TclLanguageToolkit;
import org.eclipse.dltk.tcl.core.TclNature;
import org.eclipse.dltk.ui.util.BusyIndicatorRunnableContext;
import org.eclipse.dltk.ui.util.IStatusChangeListener;
import org.eclipse.dltk.ui.wizards.BuildpathsBlock;
import org.eclipse.dltk.ui.wizards.NewElementWizardPage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
/**
* Standard wizard page for creating new Script projects. This page can be used
* in project creation wizards for projects and will configure the project with
* the Script nature. This page also allows the user to configure the Script
* project's output location for class files generated by the Script builder.
* <p>
* Whenever possible clients should use the class
* <code>ScriptCapabilityConfigurationPage
* </code> in favor of this class.
* </p>
* <p>
* Clients may instantiate or subclass.
* </p>
*/
public class NewTclProjectWizardPage extends NewElementWizardPage {
public static final String TCL_NATURE = TclNature.NATURE_ID;
private static final String PAGE_NAME = "NewScriptProjectWizardPage"; //$NON-NLS-1$
private WizardNewProjectCreationPage fMainPage;
private IBuildpathEntry[] fBuildpathEntries;
private BuildpathsBlock fBuildPathsBlock;
private boolean fProjectModified;
/**
* Creates a Script project wizard creation page.
* <p>
* The Script project wizard reads project name and location from the main
* page.
* </p>
*
* @param root
* the workspace root
* @param mainpage
* the main page of the wizard
*/
public NewTclProjectWizardPage(IWorkspaceRoot root,
WizardNewProjectCreationPage mainpage) {
super(PAGE_NAME);
setTitle(NewWizardMessages.NewScriptProjectWizardPage_title);
setDescription(NewWizardMessages.NewScriptProjectWizardPage_description);
fMainPage = mainpage;
class BuildpathBlockListener implements IStatusChangeListener,
IScriptLanguageProvider {
public void statusChanged(IStatus status) {
updateStatus(status);
}
public IDLTKLanguageToolkit getLanguageToolkit() {
return TclLanguageToolkit.getDefault();
}
}
fBuildPathsBlock = new BuildpathsBlock(
new BusyIndicatorRunnableContext(),
new BuildpathBlockListener(), 0, false, null);
fProjectModified = true;
fBuildpathEntries = null;
}
/**
* Sets the default buildpath to be used for the new Script project.
* <p>
* The caller of this method is responsible for creating the buildpath
* entries for the <code>IScriptProject</code> that corresponds to the
* created project. The caller is responsible for creating any new folders
* that might be mentioned on the buildpath.
* </p>
* <p>
* The default output location will be applied when
* <code>initBuildPaths</code> is called. This is done automatically when
* the page becomes visible and the project or the default paths have
* changed.
* </p>
*
* @param entries
* the default buildpath entries
* @param appendDefaultInterpreterEnvironment
* <code>true</code> a variable entry for the default
* InterpreterEnvironment (specified in the preferences) will be
* added to the buildpath.
*/
public void setDefaultBuildPath(IBuildpathEntry[] entries,
boolean appendDefaultInterpreterEnvironment) {
if (entries != null && appendDefaultInterpreterEnvironment) {
IBuildpathEntry[] newEntries = new IBuildpathEntry[entries.length];
System.arraycopy(entries, 0, newEntries, 0, entries.length);
entries = newEntries;
}
fBuildpathEntries = entries;
setProjectModified();
}
/**
* Sets the project state to modified. Doing so will initialize the page the
* next time it becomes visible.
*
*
*/
public void setProjectModified() {
fProjectModified = true;
}
/**
* Returns the project handle. Subclasses should override this method if
* they don't provide a main page or if they provide their own main page
* implementation.
*
* @return the project handle
*/
protected IProject getProjectHandle() {
Assert.isNotNull(fMainPage);
return fMainPage.getProjectHandle();
}
/**
* Returns the project location path. Subclasses should override this method
* if they don't provide a main page or if they provide their own main page
* implementation.
*
* @return the project location path
*/
protected IPath getLocationPath() {
Assert.isNotNull(fMainPage);
return fMainPage.getLocationPath();
}
/**
* Returns the Script project handle by converting the result of
* <code>getProjectHandle()</code> into a Script project.
*
* @return the Script project handle
* @see #getProjectHandle()
*/
public IScriptProject getNewScriptProject() {
return DLTKCore.create(getProjectHandle());
}
/*
* (non-Javadoc)
*
* @see WizardPage#createControl
*/
public void createControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
composite.setLayout(new GridLayout(1, false));
Control control = fBuildPathsBlock.createControl(composite);
control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Dialog.applyDialogFont(composite);
if (DLTKCore.DEBUG) {
System.err.println("Add help support here...");
}
// PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
// IScriptHelpContextIds.NEW_TCLPROJECT_WIZARD_PAGE);
setControl(composite);
}
/**
* Forces the initialization of the Script project page. Default buildpath
* or buildpath will be used if set. The initialization should only be
* performed when the project or default paths have changed. Toggling back
* and forward the pages without changes should not re-initialize the page,
* as changes from the user will be overwritten.
*
*
*/
protected void initBuildPaths() {
fBuildPathsBlock.init(getNewScriptProject(), fBuildpathEntries);
}
/**
* Extend this method to set a user defined default buildpath or output
* location. The method <code>initBuildPaths</code> is called when the page
* becomes visible the first time or the project or the default paths have
* changed.
*
* @param visible
* if <code>true</code> the page becomes visible; otherwise it
* becomes invisible
*/
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
// evaluate if a initialization is required
if (fProjectModified || isNewProjectHandle()) {
// only initialize the project when needed
initBuildPaths();
fProjectModified = false;
}
}
}
private boolean isNewProjectHandle() {
IProject oldProject = fBuildPathsBlock.getScriptProject().getProject();
return !oldProject.equals(getProjectHandle());
}
/**
* Returns the currently configured buildpath. Note that the buildpath might
* not be valid.
*
* @return the configured buildpath
*
*
*/
public IBuildpathEntry[] getRawBuildPath() {
return fBuildPathsBlock.getRawBuildPath();
}
/**
* Returns the runnable that will create the Script project. The runnable
* will create and open the project if needed. The runnable will add the
* Script nature to the project, and set the project's buildpath and output
* location.
* <p>
* To create the new Tcl project, execute this runnable
* </p>
*
* @return the runnable
*/
public IRunnableWithProgress getRunnable() {
return new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
monitor.beginTask(
NewWizardMessages.NewScriptProjectWizardPage_op_desc,
10);
// initialize if needed
if (fProjectModified || isNewProjectHandle()) {
initBuildPaths();
}
// create the project
try {
IPath locationPath = getLocationPath();
BuildpathsBlock.createProject(getProjectHandle(),
locationPath != null ? URIUtil.toURI(locationPath)
: null, new SubProgressMonitor(monitor, 2));
BuildpathsBlock.addScriptNature(getProjectHandle(),
new SubProgressMonitor(monitor, 2), TCL_NATURE);
fBuildPathsBlock
.configureScriptProject(new SubProgressMonitor(
monitor, 6));
} catch (CoreException e) {
throw new InvocationTargetException(e);
} catch (OperationCanceledException e) {
throw new InterruptedException();
} finally {
monitor.done();
}
}
};
}
}