• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.lint;
18 
19 import static com.android.SdkConstants.DOT_XML;
20 
21 import com.android.ide.eclipse.adt.AdtPlugin;
22 import com.android.ide.eclipse.adt.AdtUtils;
23 import com.android.ide.eclipse.adt.internal.editors.IconFactory;
24 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
25 import com.android.tools.lint.detector.api.LintUtils;
26 
27 import org.eclipse.core.resources.IFile;
28 import org.eclipse.core.resources.IProject;
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.jdt.core.IJavaProject;
31 import org.eclipse.jdt.ui.JavaElementLabelProvider;
32 import org.eclipse.jface.action.Action;
33 import org.eclipse.jface.action.ActionContributionItem;
34 import org.eclipse.jface.action.IAction;
35 import org.eclipse.jface.action.IMenuCreator;
36 import org.eclipse.jface.action.Separator;
37 import org.eclipse.jface.dialogs.MessageDialog;
38 import org.eclipse.jface.resource.ImageDescriptor;
39 import org.eclipse.jface.viewers.ILabelProvider;
40 import org.eclipse.jface.viewers.ISelection;
41 import org.eclipse.swt.widgets.Control;
42 import org.eclipse.swt.widgets.Menu;
43 import org.eclipse.ui.IObjectActionDelegate;
44 import org.eclipse.ui.ISharedImages;
45 import org.eclipse.ui.IWorkbenchPart;
46 import org.eclipse.ui.IWorkbenchWindow;
47 import org.eclipse.ui.IWorkbenchWindowPulldownDelegate;
48 import org.eclipse.ui.PlatformUI;
49 import org.eclipse.ui.texteditor.ITextEditor;
50 
51 import java.util.ArrayList;
52 import java.util.List;
53 
54 /**
55  * Action which runs Lint on the currently projects (and also provides a
56  * pulldown menu in the toolbar for selecting specifically which projects to
57  * check)
58  */
59 public class RunLintAction implements IObjectActionDelegate, IMenuCreator,
60         IWorkbenchWindowPulldownDelegate {
61 
62     private ISelection mSelection;
63     private Menu mMenu;
64 
65     @Override
selectionChanged(IAction action, ISelection selection)66     public void selectionChanged(IAction action, ISelection selection) {
67         mSelection = selection;
68     }
69 
70     @Override
run(IAction action)71     public void run(IAction action) {
72         List<IProject> projects = getProjects(mSelection, true /* warn */);
73 
74         if (!projects.isEmpty()) {
75             EclipseLintRunner.startLint(projects, null, null, false /*fatalOnly*/, true /*show*/);
76         }
77     }
78 
79     /** Returns the Android project(s) to apply a lint run to. */
getProjects(ISelection selection, boolean warn)80     static List<IProject> getProjects(ISelection selection, boolean warn) {
81         List<IProject> projects = AdtUtils.getSelectedProjects(selection);
82 
83         if (projects.isEmpty() && warn) {
84             MessageDialog.openWarning(AdtPlugin.getShell(), "Lint",
85                     "Could not run Lint: Select an Android project first.");
86         }
87 
88         return projects;
89     }
90 
91     @Override
setActivePart(IAction action, IWorkbenchPart targetPart)92     public void setActivePart(IAction action, IWorkbenchPart targetPart) {
93     }
94 
95     @Override
dispose()96     public void dispose() {
97         if (mMenu != null) {
98             mMenu.dispose();
99         }
100     }
101 
102     @Override
init(IWorkbenchWindow window)103     public void init(IWorkbenchWindow window) {
104     }
105 
106     // ---- IMenuCreator ----
107 
108     @Override
getMenu(Control parent)109     public Menu getMenu(Control parent) {
110         mMenu = new Menu(parent);
111 
112         IconFactory iconFactory = IconFactory.getInstance();
113         ImageDescriptor allIcon = iconFactory.getImageDescriptor("lintrun"); //$NON-NLS-1$
114         LintMenuAction allAction = new LintMenuAction("Check All Projects", allIcon,
115                 ACTION_RUN, null);
116 
117         addAction(allAction);
118         addSeparator();
119         IJavaProject[] projects = AdtUtils.getOpenAndroidProjects();
120         ILabelProvider provider = new JavaElementLabelProvider(
121                 JavaElementLabelProvider.SHOW_DEFAULT);
122         for (IJavaProject project : projects) {
123             IProject p = project.getProject();
124             ImageDescriptor icon = ImageDescriptor.createFromImage(provider.getImage(p));
125             String label = String.format("Check %1$s", p.getName());
126             LintMenuAction projectAction = new LintMenuAction(label, icon, ACTION_RUN, p);
127             addAction(projectAction);
128         }
129 
130         ITextEditor textEditor = AdtUtils.getActiveTextEditor();
131         if (textEditor != null) {
132             IFile file = AdtUtils.getActiveFile();
133             // Currently only supported for XML files
134             if (file != null && LintUtils.endsWith(file.getName(), DOT_XML)) {
135                 ImageDescriptor icon = ImageDescriptor.createFromImage(provider.getImage(file));
136                 IAction fileAction = new LintMenuAction("Check Current File", icon, ACTION_RUN,
137                         file);
138 
139                 addSeparator();
140                 addAction(fileAction);
141             }
142         }
143 
144         ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
145         ImageDescriptor clear = images.getImageDescriptor(ISharedImages.IMG_ELCL_REMOVEALL);
146         LintMenuAction clearAction = new LintMenuAction("Clear Lint Warnings", clear, ACTION_CLEAR,
147                 null);
148         addSeparator();
149         addAction(clearAction);
150 
151         LintMenuAction excludeAction = new LintMenuAction("Skip Library Project Dependencies",
152                 allIcon, ACTION_TOGGLE_EXCLUDE, null);
153         addSeparator();
154         addAction(excludeAction);
155         excludeAction.setChecked(AdtPrefs.getPrefs().getSkipLibrariesFromLint());
156 
157         return mMenu;
158     }
159 
addAction(IAction action)160     private void addAction(IAction action) {
161         ActionContributionItem item = new ActionContributionItem(action);
162         item.fill(mMenu, -1);
163     }
164 
addSeparator()165     private void addSeparator() {
166         new Separator().fill(mMenu, -1);
167     }
168 
169     @Override
getMenu(Menu parent)170     public Menu getMenu(Menu parent) {
171         return null;
172     }
173 
174     private static final int ACTION_RUN = 1;
175     private static final int ACTION_CLEAR = 2;
176     private static final int ACTION_TOGGLE_EXCLUDE = 3;
177 
178     /**
179      * Actions in the pulldown context menu: run lint or clear lint markers on
180      * the given resource
181      */
182     private static class LintMenuAction extends Action {
183         private final IResource mResource;
184         private final int mAction;
185 
186         /**
187          * Creates a new context menu action
188          *
189          * @param text the label
190          * @param descriptor the icon
191          * @param action the action to run: run lint, clear, or toggle exclude libraries
192          * @param resource the resource to check or clear markers for, where
193          *            null means all projects
194          */
LintMenuAction(String text, ImageDescriptor descriptor, int action, IResource resource)195         private LintMenuAction(String text, ImageDescriptor descriptor, int action,
196                 IResource resource) {
197             super(text, action == ACTION_TOGGLE_EXCLUDE ? AS_CHECK_BOX : AS_PUSH_BUTTON);
198             if (descriptor != null) {
199                 setImageDescriptor(descriptor);
200             }
201             mAction = action;
202             mResource = resource;
203         }
204 
205         @Override
run()206         public void run() {
207             if (mAction == ACTION_TOGGLE_EXCLUDE) {
208                 AdtPrefs prefs = AdtPrefs.getPrefs();
209                 prefs.setSkipLibrariesFromLint(!prefs.getSkipLibrariesFromLint());
210                 return;
211             }
212             List<IResource> resources = new ArrayList<IResource>();
213             if (mResource == null) {
214                 // All projects
215                 IJavaProject[] open = AdtUtils.getOpenAndroidProjects();
216                 for (IJavaProject project : open) {
217                     resources.add(project.getProject());
218                 }
219             } else {
220                 resources.add(mResource);
221             }
222             EclipseLintRunner.cancelCurrentJobs(false);
223             if (mAction == ACTION_CLEAR) {
224                 EclipseLintClient.clearMarkers(resources);
225             } else {
226                 assert mAction == ACTION_RUN;
227                 EclipseLintRunner.startLint(resources, null, null, false /*fatalOnly*/,
228                         true /*show*/);
229             }
230         }
231     }
232 }
233