/* * Copyright (C) 2008 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.project; import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper.IProjectFilter; import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.Sdk; 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.viewers.ILabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.dialogs.ElementListSelectionDialog; /** * Helper class to deal with displaying a project choosing dialog that lists only the * projects with the Android nature. */ public class ProjectChooserHelper { private final Shell mParentShell; private final IProjectChooserFilter mFilter; /** * List of current android projects. Since the dialog is modal, we'll just get * the list once on-demand. */ private IJavaProject[] mAndroidProjects; /** * Interface to filter out some project displayed by {@link ProjectChooserHelper}. * * @see IProjectFilter */ public interface IProjectChooserFilter extends IProjectFilter { /** * Whether the Project Chooser can compute the project list once and cache the result. *
If false the project list is recomputed every time the dialog is opened. */ boolean useCache(); } /** * An implementation of {@link IProjectChooserFilter} that only displays non-library projects. */ public final static class NonLibraryProjectOnlyFilter implements IProjectChooserFilter { @Override public boolean accept(IProject project) { ProjectState state = Sdk.getProjectState(project); if (state != null) { return state.isLibrary() == false; } return false; } @Override public boolean useCache() { return true; } } /** * An implementation of {@link IProjectChooserFilter} that only displays library projects. */ public final static class LibraryProjectOnlyFilter implements IProjectChooserFilter { @Override public boolean accept(IProject project) { ProjectState state = Sdk.getProjectState(project); if (state != null ) { return state.isLibrary(); } return false; } @Override public boolean useCache() { return true; } } /** * Creates a new project chooser. * @param parentShell the parent {@link Shell} for the dialog. * @param filter a filter to only accept certain projects. Can be null. */ public ProjectChooserHelper(Shell parentShell, IProjectChooserFilter filter) { mParentShell = parentShell; mFilter = filter; } /** * Displays a project chooser dialog which lists all available projects with the Android nature. * * The list of project is built from Android flagged projects currently opened in the workspace. * * @param projectName If non null and not empty, represents the name of an Android project * that will be selected by default. * @param message Message for the dialog box. Can be null in which case a default message * is displayed. * @return the project chosen by the user in the dialog, or null if the dialog was canceled. */ public IJavaProject chooseJavaProject(String projectName, String message) { ILabelProvider labelProvider = new JavaElementLabelProvider( JavaElementLabelProvider.SHOW_DEFAULT); ElementListSelectionDialog dialog = new ElementListSelectionDialog( mParentShell, labelProvider); dialog.setTitle("Project Selection"); if (message == null) { message = "Please select a project"; } dialog.setMessage(message); IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IJavaModel javaModel = JavaCore.create(workspaceRoot); // set the elements in the dialog. These are opened android projects. dialog.setElements(getAndroidProjects(javaModel)); // look for the project matching the given project name IJavaProject javaProject = null; if (projectName != null && projectName.length() > 0) { javaProject = javaModel.getJavaProject(projectName); } // if we found it, we set the initial selection in the dialog to this one. if (javaProject != null) { dialog.setInitialSelections(new Object[] { javaProject }); } // open the dialog and return the object selected if OK was clicked, or null otherwise if (dialog.open() == Window.OK) { return (IJavaProject) dialog.getFirstResult(); } return null; } /** * Returns the list of Android projects. * * Because this list can be time consuming, this class caches the list of project. * It is recommended to call this method instead of * {@link BaseProjectHelper#getAndroidProjects()}. * * @param javaModel the java model. Can be null. */ public IJavaProject[] getAndroidProjects(IJavaModel javaModel) { // recompute only if we don't have the projects already or the filter is dynamic // and prevent usage of a cache. if (mAndroidProjects == null || (mFilter != null && mFilter.useCache() == false)) { if (javaModel == null) { mAndroidProjects = BaseProjectHelper.getAndroidProjects(mFilter); } else { mAndroidProjects = BaseProjectHelper.getAndroidProjects(javaModel, mFilter); } } return mAndroidProjects; } /** * Helper method to get the Android project with the given name * * @param projectName the name of the project to find * @return the {@link IProject} for the Android project.null
if not found.
*/
public IProject getAndroidProject(String projectName) {
IProject iproject = null;
IJavaProject[] javaProjects = getAndroidProjects(null);
if (javaProjects != null) {
for (IJavaProject javaProject : javaProjects) {
if (javaProject.getElementName().equals(projectName)) {
iproject = javaProject.getProject();
break;
}
}
}
return iproject;
}
/**
* A selector combo for showing the currently selected project and for
* changing the selection
*/
public static class ProjectCombo extends Combo implements SelectionListener {
/** Currently chosen project, or null when no project has been initialized or selected */
private IProject mProject;
private IJavaProject[] mAvailableProjects;
/**
* Creates a new project selector combo
*
* @param helper associated {@link ProjectChooserHelper} for looking up
* projects
* @param parent parent composite to add the combo to
* @param initialProject the initial project to select, or null (which
* will show a "Please Choose Project..." label instead.)
*/
public ProjectCombo(ProjectChooserHelper helper, Composite parent,
IProject initialProject) {
super(parent, SWT.BORDER | SWT.FLAT | SWT.READ_ONLY);
mProject = initialProject;
mAvailableProjects = helper.getAndroidProjects(null);
String[] items = new String[mAvailableProjects.length + 1];
items[0] = "--- Choose Project ---";
ILabelProvider labelProvider = new JavaElementLabelProvider(
JavaElementLabelProvider.SHOW_DEFAULT);
int selectionIndex = 0;
for (int i = 0, n = mAvailableProjects.length; i < n; i++) {
IProject project = mAvailableProjects[i].getProject();
items[i + 1] = labelProvider.getText(project);
if (project == initialProject) {
selectionIndex = i + 1;
}
}
setItems(items);
select(selectionIndex);
addSelectionListener(this);
}
/**
* Returns the project selected by this chooser (or the initial project
* passed to the constructor if the user did not change it)
*
* @return the selected project
*/
public IProject getSelectedProject() {
return mProject;
}
/**
* Sets the project selected by this chooser
*
* @param project the selected project
*/
public void setSelectedProject(IProject project) {
mProject = project;
int selectionIndex = 0;
for (int i = 0, n = mAvailableProjects.length; i < n; i++) {
if (project == mAvailableProjects[i].getProject()) {
selectionIndex = i + 1; // +1: Slot 0 is reserved for "Choose Project"
select(selectionIndex);
break;
}
}
}
/**
* Click handler for the button: Open the {@link ProjectChooserHelper}
* dialog for selecting a new project.
*/
@Override
public void widgetSelected(SelectionEvent e) {
int selectionIndex = getSelectionIndex();
if (selectionIndex > 0 && mAvailableProjects != null
&& selectionIndex <= mAvailableProjects.length) {
// selection index 0 is "Choose Project", all other projects are offset
// by 1 from the selection index
mProject = mAvailableProjects[selectionIndex - 1].getProject();
} else {
mProject = null;
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}
}