blob: 19724708328f7bb35970c563d56e17a04b13213f [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.adt.internal.wizards.newproject;
import com.android.SdkConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
import com.android.sdklib.IAndroidTarget;
import com.android.utils.Pair;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import java.io.File;
/** Page where the user can select a sample to "instantiate" */
class SampleSelectionPage extends WizardPage implements SelectionListener, ModifyListener {
private final NewProjectWizardState mValues;
private boolean mIgnore;
private Table mTable;
private TableViewer mTableViewer;
private IAndroidTarget mCurrentSamplesTarget;
private Text mSampleProjectName;
/**
* Create the wizard.
*/
SampleSelectionPage(NewProjectWizardState values) {
super("samplePage"); //$NON-NLS-1$
setTitle("Select Sample");
setDescription("Select which sample to create");
mValues = values;
}
/**
* Create contents of the wizard.
*/
@Override
public void createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
container.setLayout(new GridLayout(2, false));
mTableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION);
mTable = mTableViewer.getTable();
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
gridData.heightHint = 300;
mTable.setLayoutData(gridData);
mTable.addSelectionListener(this);
setControl(container);
Label projectLabel = new Label(container, SWT.NONE);
projectLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
projectLabel.setText("Project Name:");
mSampleProjectName = new Text(container, SWT.BORDER);
mSampleProjectName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
mSampleProjectName.addModifyListener(this);
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
if (mValues.projectName != null) {
try {
mIgnore = true;
mSampleProjectName.setText(mValues.projectName);
} finally {
mIgnore = false;
}
}
// Update samples list if the SDK target has changed (or if it hasn't yet
// been populated)
if (mCurrentSamplesTarget != mValues.target) {
mCurrentSamplesTarget = mValues.target;
updateSamples();
}
validatePage();
}
}
private void updateSamples() {
IBaseLabelProvider labelProvider = new ColumnLabelProvider() {
@Override
public Image getImage(Object element) {
return AdtPlugin.getAndroidLogo();
}
@Override
public String getText(Object element) {
if (element instanceof Pair<?, ?>) {
Object name = ((Pair<?, ?>) element).getFirst();
return name.toString();
}
return element.toString(); // Fallback. Should not happen.
}
};
mTableViewer.setContentProvider(new ArrayContentProvider());
mTableViewer.setLabelProvider(labelProvider);
if (mValues.samples != null && mValues.samples.size() > 0) {
Object[] samples = mValues.samples.toArray();
mTableViewer.setInput(samples);
mTable.select(0);
selectSample(mValues.samples.get(0).getSecond());
extractNamesFromAndroidManifest();
}
}
private void selectSample(File sample) {
mValues.chosenSample = sample;
if (sample != null && !mValues.projectNameModifiedByUser) {
mValues.projectName = sample.getName();
if (SdkConstants.FD_SAMPLE.equals(mValues.projectName) &&
sample.getParentFile() != null) {
mValues.projectName = sample.getParentFile().getName() + '_' + mValues.projectName;
}
try {
mIgnore = true;
mSampleProjectName.setText(mValues.projectName);
} finally {
mIgnore = false;
}
updatedProjectName();
}
}
@SuppressWarnings("unchecked")
@Override
public void widgetSelected(SelectionEvent e) {
if (mIgnore) {
return;
}
if (e.getSource() == mTable) {
extractNamesFromAndroidManifest();
int index = mTable.getSelectionIndex();
if (index >= 0) {
Object[] roots = (Object[]) mTableViewer.getInput();
selectSample(((Pair<String, File>) roots[index]).getSecond());
} else {
selectSample(null);
}
} else {
assert false : e.getSource();
}
validatePage();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
@Override
public void modifyText(ModifyEvent e) {
if (mIgnore) {
return;
}
if (e.getSource() == mSampleProjectName) {
mValues.projectName = mSampleProjectName.getText().trim();
mValues.projectNameModifiedByUser = true;
updatedProjectName();
}
validatePage();
}
private void updatedProjectName() {
if (mValues.useDefaultLocation) {
mValues.projectLocation = Platform.getLocation().toFile();
}
}
/**
* A sample was selected. Update the location field, manifest and validate.
* Extract names from an android manifest.
* This is done only if the user selected the "use existing source" and a manifest xml file
* can actually be found in the custom user directory.
*/
private void extractNamesFromAndroidManifest() {
if (mValues.chosenSample == null || !mValues.chosenSample.isDirectory()) {
return;
}
Path path = new Path(mValues.chosenSample.getPath());
mValues.extractFromAndroidManifest(path);
}
@Override
public boolean isPageComplete() {
if (mValues.mode != Mode.SAMPLE) {
return true;
}
// Ensure that when creating samples, the Finish button isn't enabled until
// the user has reached and completed this page
if (mValues.chosenSample == null) {
return false;
}
return super.isPageComplete();
}
private void validatePage() {
IStatus status = null;
if (mValues.samples == null || mValues.samples.size() == 0) {
status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
"The chosen SDK does not contain any samples");
} else if (mValues.chosenSample == null) {
status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "Choose a sample");
} else if (!mValues.chosenSample.exists()) {
status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
String.format("Sample does not exist: %1$s", mValues.chosenSample.getPath()));
} else {
status = ProjectNamePage.validateProjectName(mValues.projectName);
}
// -- update UI & enable finish if there's no error
setPageComplete(status == null || status.getSeverity() != IStatus.ERROR);
if (status != null) {
setMessage(status.getMessage(),
status.getSeverity() == IStatus.ERROR
? IMessageProvider.ERROR : IMessageProvider.WARNING);
} else {
setErrorMessage(null);
setMessage(null);
}
}
}