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