• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.eclipse.adt.internal.project;
18 
19 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper.IProjectFilter;
20 import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
21 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
22 
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.resources.IWorkspaceRoot;
25 import org.eclipse.core.resources.ResourcesPlugin;
26 import org.eclipse.jdt.core.IJavaModel;
27 import org.eclipse.jdt.core.IJavaProject;
28 import org.eclipse.jdt.core.JavaCore;
29 import org.eclipse.jdt.ui.JavaElementLabelProvider;
30 import org.eclipse.jface.viewers.ILabelProvider;
31 import org.eclipse.jface.window.Window;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.SelectionEvent;
34 import org.eclipse.swt.events.SelectionListener;
35 import org.eclipse.swt.widgets.Combo;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Shell;
38 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
39 
40 /**
41  * Helper class to deal with displaying a project choosing dialog that lists only the
42  * projects with the Android nature.
43  */
44 public class ProjectChooserHelper {
45 
46     private final Shell mParentShell;
47     private final IProjectChooserFilter mFilter;
48 
49     /**
50      * List of current android projects. Since the dialog is modal, we'll just get
51      * the list once on-demand.
52      */
53     private IJavaProject[] mAndroidProjects;
54 
55     /**
56      * Interface to filter out some project displayed by {@link ProjectChooserHelper}.
57      *
58      * @see IProjectFilter
59      */
60     public interface IProjectChooserFilter extends IProjectFilter {
61         /**
62          * Whether the Project Chooser can compute the project list once and cache the result.
63          * </p>If false the project list is recomputed every time the dialog is opened.
64          */
useCache()65         boolean useCache();
66     }
67 
68     /**
69      * An implementation of {@link IProjectChooserFilter} that only displays non-library projects.
70      */
71     public final static class NonLibraryProjectOnlyFilter implements IProjectChooserFilter {
accept(IProject project)72         public boolean accept(IProject project) {
73             ProjectState state = Sdk.getProjectState(project);
74             if (state != null) {
75                 return state.isLibrary() == false;
76             }
77 
78             return false;
79         }
80 
useCache()81         public boolean useCache() {
82             return true;
83         }
84     }
85 
86     /**
87      * An implementation of {@link IProjectChooserFilter} that only displays library projects.
88      */
89     public final static class LibraryProjectOnlyFilter implements IProjectChooserFilter {
accept(IProject project)90         public boolean accept(IProject project) {
91             ProjectState state = Sdk.getProjectState(project);
92             if (state != null ) {
93                 return state.isLibrary();
94             }
95 
96             return false;
97         }
98 
useCache()99         public boolean useCache() {
100             return true;
101         }
102     }
103 
104     /**
105      * Creates a new project chooser.
106      * @param parentShell the parent {@link Shell} for the dialog.
107      * @param filter a filter to only accept certain projects. Can be null.
108      */
ProjectChooserHelper(Shell parentShell, IProjectChooserFilter filter)109     public ProjectChooserHelper(Shell parentShell, IProjectChooserFilter filter) {
110         mParentShell = parentShell;
111         mFilter = filter;
112     }
113 
114     /**
115      * Displays a project chooser dialog which lists all available projects with the Android nature.
116      * <p/>
117      * The list of project is built from Android flagged projects currently opened in the workspace.
118      *
119      * @param projectName If non null and not empty, represents the name of an Android project
120      *                    that will be selected by default.
121      * @param message Message for the dialog box. Can be null in which case a default message
122      *                is displayed.
123      * @return the project chosen by the user in the dialog, or null if the dialog was canceled.
124      */
chooseJavaProject(String projectName, String message)125     public IJavaProject chooseJavaProject(String projectName, String message) {
126         ILabelProvider labelProvider = new JavaElementLabelProvider(
127                 JavaElementLabelProvider.SHOW_DEFAULT);
128         ElementListSelectionDialog dialog = new ElementListSelectionDialog(
129                 mParentShell, labelProvider);
130         dialog.setTitle("Project Selection");
131         if (message == null) {
132             message = "Please select a project";
133         }
134         dialog.setMessage(message);
135 
136         IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
137         IJavaModel javaModel = JavaCore.create(workspaceRoot);
138 
139         // set the elements in the dialog. These are opened android projects.
140         dialog.setElements(getAndroidProjects(javaModel));
141 
142         // look for the project matching the given project name
143         IJavaProject javaProject = null;
144         if (projectName != null && projectName.length() > 0) {
145             javaProject = javaModel.getJavaProject(projectName);
146         }
147 
148         // if we found it, we set the initial selection in the dialog to this one.
149         if (javaProject != null) {
150             dialog.setInitialSelections(new Object[] { javaProject });
151         }
152 
153         // open the dialog and return the object selected if OK was clicked, or null otherwise
154         if (dialog.open() == Window.OK) {
155             return (IJavaProject) dialog.getFirstResult();
156         }
157         return null;
158     }
159 
160     /**
161      * Returns the list of Android projects.
162      * <p/>
163      * Because this list can be time consuming, this class caches the list of project.
164      * It is recommended to call this method instead of
165      * {@link BaseProjectHelper#getAndroidProjects()}.
166      *
167      * @param javaModel the java model. Can be null.
168      */
getAndroidProjects(IJavaModel javaModel)169     public IJavaProject[] getAndroidProjects(IJavaModel javaModel) {
170         // recompute only if we don't have the projects already or the filter is dynamic
171         // and prevent usage of a cache.
172         if (mAndroidProjects == null || (mFilter != null && mFilter.useCache() == false)) {
173             if (javaModel == null) {
174                 mAndroidProjects = BaseProjectHelper.getAndroidProjects(mFilter);
175             } else {
176                 mAndroidProjects = BaseProjectHelper.getAndroidProjects(javaModel, mFilter);
177             }
178         }
179 
180         return mAndroidProjects;
181     }
182 
183     /**
184      * Helper method to get the Android project with the given name
185      *
186      * @param projectName the name of the project to find
187      * @return the {@link IProject} for the Android project. <code>null</code> if not found.
188      */
getAndroidProject(String projectName)189     public IProject getAndroidProject(String projectName) {
190         IProject iproject = null;
191         IJavaProject[] javaProjects = getAndroidProjects(null);
192         if (javaProjects != null) {
193             for (IJavaProject javaProject : javaProjects) {
194                 if (javaProject.getElementName().equals(projectName)) {
195                     iproject = javaProject.getProject();
196                     break;
197                 }
198             }
199         }
200         return iproject;
201     }
202 
203     /**
204      * A selector combo for showing the currently selected project and for
205      * changing the selection
206      */
207     public static class ProjectCombo extends Combo implements SelectionListener {
208         /** Currently chosen project, or null when no project has been initialized or selected */
209         private IProject mProject;
210         private IJavaProject[] mAvailableProjects;
211 
212         /**
213          * Creates a new project selector combo
214          *
215          * @param helper associated {@link ProjectChooserHelper} for looking up
216          *            projects
217          * @param parent parent composite to add the combo to
218          * @param initialProject the initial project to select, or null (which
219          *            will show a "Please Choose Project..." label instead.)
220          */
ProjectCombo(ProjectChooserHelper helper, Composite parent, IProject initialProject)221         public ProjectCombo(ProjectChooserHelper helper, Composite parent,
222                 IProject initialProject) {
223             super(parent, SWT.BORDER | SWT.FLAT | SWT.READ_ONLY);
224             mProject = initialProject;
225 
226             mAvailableProjects = helper.getAndroidProjects(null);
227             String[] items = new String[mAvailableProjects.length + 1];
228             items[0] = "--- Choose Project ---";
229 
230             ILabelProvider labelProvider = new JavaElementLabelProvider(
231                     JavaElementLabelProvider.SHOW_DEFAULT);
232             int selectionIndex = 0;
233             for (int i = 0, n = mAvailableProjects.length; i < n; i++) {
234                 IProject project = mAvailableProjects[i].getProject();
235                 items[i + 1] = labelProvider.getText(project);
236                 if (project == initialProject) {
237                     selectionIndex = i + 1;
238                 }
239             }
240             setItems(items);
241             select(selectionIndex);
242 
243             addSelectionListener(this);
244         }
245 
246         /**
247          * Returns the project selected by this chooser (or the initial project
248          * passed to the constructor if the user did not change it)
249          *
250          * @return the selected project
251          */
getSelectedProject()252         public IProject getSelectedProject() {
253             return mProject;
254         }
255 
256         /**
257          * Sets the project selected by this chooser
258          *
259          * @param project the selected project
260          */
setSelectedProject(IProject project)261         public void setSelectedProject(IProject project) {
262             mProject = project;
263 
264             int selectionIndex = 0;
265             for (int i = 0, n = mAvailableProjects.length; i < n; i++) {
266                 if (project == mAvailableProjects[i].getProject()) {
267                     selectionIndex = i + 1; // +1: Slot 0 is reserved for "Choose Project"
268                     select(selectionIndex);
269                     break;
270                 }
271             }
272         }
273 
274         /**
275          * Click handler for the button: Open the {@link ProjectChooserHelper}
276          * dialog for selecting a new project.
277          */
widgetSelected(SelectionEvent e)278         public void widgetSelected(SelectionEvent e) {
279             int selectionIndex = getSelectionIndex();
280             if (selectionIndex > 0 && mAvailableProjects != null
281                     && selectionIndex <= mAvailableProjects.length) {
282                 // selection index 0 is "Choose Project", all other projects are offset
283                 // by 1 from the selection index
284                 mProject = mAvailableProjects[selectionIndex - 1].getProject();
285             } else {
286                 mProject = null;
287             }
288         }
289 
widgetDefaultSelected(SelectionEvent e)290         public void widgetDefaultSelected(SelectionEvent e) {
291         }
292 
293         @Override
checkSubclass()294         protected void checkSubclass() {
295             // Disable the check that prevents subclassing of SWT components
296         }
297     }
298 }
299