| /* |
| * 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); |
| } |
| } |
| } |