blob: f1c188ae99294b67dd06e09a248b67e6475c36b1 [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.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.ui.dialogs.FilteredList;
/**
* Page shown when creating a test project which lets you choose between testing
* yourself and testing a different project
*/
class TestTargetPage extends WizardPage implements SelectionListener {
private final NewProjectWizardState mValues;
/** Flag used when setting button/text state manually to ignore listener updates */
private boolean mIgnore;
private String mLastExistingPackageName;
private Button mCurrentRadioButton;
private Button mExistingRadioButton;
private FilteredList mProjectList;
private boolean mPageShown;
/**
* Create the wizard.
*/
TestTargetPage(NewProjectWizardState values) {
super("testTargetPage"); //$NON-NLS-1$
setTitle("Select Test Target");
setDescription("Choose a project to test");
mValues = values;
}
/**
* Create contents of the wizard.
*/
@Override
public void createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
setControl(container);
container.setLayout(new GridLayout(2, false));
mCurrentRadioButton = new Button(container, SWT.RADIO);
mCurrentRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
mCurrentRadioButton.setText("This project");
mCurrentRadioButton.addSelectionListener(this);
mExistingRadioButton = new Button(container, SWT.RADIO);
mExistingRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
mExistingRadioButton.setText("An existing Android project:");
mExistingRadioButton.addSelectionListener(this);
ILabelProvider labelProvider = new JavaElementLabelProvider(
JavaElementLabelProvider.SHOW_DEFAULT);
mProjectList = new FilteredList(container,
SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE, labelProvider,
true /*ignoreCase*/, false /*allowDuplicates*/, true /* matchEmptyString*/);
mProjectList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
mProjectList.addSelectionListener(this);
}
private void initializeList() {
ProjectChooserHelper helper = new ProjectChooserHelper(getShell(), null /*filter*/);
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IJavaModel javaModel = JavaCore.create(workspaceRoot);
IJavaProject[] androidProjects = helper.getAndroidProjects(javaModel);
mProjectList.setElements(androidProjects);
if (mValues.testedProject != null) {
for (IJavaProject project : androidProjects) {
if (project.getProject() == mValues.testedProject) {
mProjectList.setSelection(new Object[] { project });
break;
}
}
} else {
// No initial selection: force the user to choose
mProjectList.setSelection(new int[0]);
}
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
mPageShown = true;
if (visible) {
try {
mIgnore = true;
mCurrentRadioButton.setSelection(mValues.testingSelf);
mExistingRadioButton.setSelection(!mValues.testingSelf);
mProjectList.setEnabled(!mValues.testingSelf);
if (mProjectList.isEmpty()) {
initializeList();
}
if (!mValues.testingSelf) {
mProjectList.setFocus();
IProject project = getSelectedProject();
if (project != null) {
// The FilteredList seems to -insist- on selecting the first item
// in the list, even when the selection is explicitly set to an empty
// array. This means the user is looking at a selection, so we need
// to also go ahead and select this item in the model such that the
// two agree, even if we would have preferred to have no initial
// selection.
mValues.testedProject = project;
}
}
} finally {
mIgnore = false;
}
}
validatePage();
}
@Override
public void widgetSelected(SelectionEvent e) {
if (mIgnore) {
return;
}
Object source = e.getSource();
if (source == mExistingRadioButton) {
mProjectList.setEnabled(true);
mValues.testingSelf = false;
setExistingProject(getSelectedProject());
mProjectList.setFocus();
} else if (source == mCurrentRadioButton) {
mProjectList.setEnabled(false);
mValues.testingSelf = true;
mValues.testedProject = null;
} else {
// The event must be from the project list, which unfortunately doesn't
// pass itself as the selection event, it passes a reference to some internal
// table widget that it uses, so we check for this case last
IProject project = getSelectedProject();
if (project != mValues.testedProject) {
setExistingProject(project);
}
}
validatePage();
}
private IProject getSelectedProject() {
Object[] selection = mProjectList.getSelection();
IProject project = selection != null && selection.length == 1
? ((IJavaProject) selection[0]).getProject() : null;
return project;
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
private void setExistingProject(IProject project) {
mValues.testedProject = project;
// Try to update the application, package, sdk target and minSdkVersion accordingly
if (project != null &&
(!mValues.applicationNameModifiedByUser ||
!mValues.packageNameModifiedByUser ||
!mValues.targetModifiedByUser ||
!mValues.minSdkModifiedByUser)) {
ManifestData manifestData = AndroidManifestHelper.parseForData(project);
if (manifestData != null) {
String appName = String.format("%1$sTest", project.getName());
String packageName = manifestData.getPackage();
String minSdkVersion = manifestData.getMinSdkVersionString();
IAndroidTarget sdkTarget = null;
if (Sdk.getCurrent() != null) {
sdkTarget = Sdk.getCurrent().getTarget(project);
}
if (packageName == null) {
packageName = ""; //$NON-NLS-1$
}
mLastExistingPackageName = packageName;
if (!mValues.projectNameModifiedByUser) {
mValues.projectName = appName;
}
if (!mValues.applicationNameModifiedByUser) {
mValues.applicationName = appName;
}
if (!mValues.packageNameModifiedByUser) {
packageName += ".test"; //$NON-NLS-1$
mValues.packageName = packageName;
}
if (!mValues.targetModifiedByUser && sdkTarget != null) {
mValues.target = sdkTarget;
}
if (!mValues.minSdkModifiedByUser) {
if (minSdkVersion != null || sdkTarget != null) {
mValues.minSdk = minSdkVersion;
}
if (sdkTarget == null) {
mValues.updateSdkTargetToMatchMinSdkVersion();
}
}
}
}
updateTestTargetPackageField(mLastExistingPackageName);
}
/**
* Updates the test target package name
*
* When using the "self-test" option, the packageName argument is ignored and the
* current value from the project package is used.
*
* Otherwise the packageName is used if it is not null.
*/
private void updateTestTargetPackageField(String packageName) {
if (mValues.testingSelf) {
mValues.testTargetPackageName = mValues.packageName;
} else if (packageName != null) {
mValues.testTargetPackageName = packageName;
}
}
@Override
public boolean isPageComplete() {
// Ensure that the user sees the page and makes a selection
if (!mPageShown) {
return false;
}
return super.isPageComplete();
}
private void validatePage() {
String error = null;
if (!mValues.testingSelf) {
if (mValues.testedProject == null) {
error = "Please select an existing Android project as a test target.";
} else if (mValues.projectName.equals(mValues.testedProject.getName())) {
error = "The main project name and the test project name must be different.";
}
}
// -- update UI & enable finish if there's no error
setPageComplete(error == null);
if (error != null) {
setMessage(error, IMessageProvider.ERROR);
} else {
setErrorMessage(null);
setMessage(null);
}
}
}