blob: 9de8ad06eb4345caf3a9e968967f39839c2b64b4 [file] [log] [blame]
/*
* 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.
* </p>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.
* <p/>
* 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.
* <p/>
* 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. <code>null</code> 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
}
}
}