• 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 package com.android.ide.eclipse.adt.internal.lint;
17 
18 import com.android.ide.eclipse.adt.AdtPlugin;
19 import com.android.ide.eclipse.adt.AdtUtils;
20 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
21 
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IMarker;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.jface.dialogs.IDialogConstants;
27 import org.eclipse.jface.dialogs.TitleAreaDialog;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.events.SelectionEvent;
30 import org.eclipse.swt.events.SelectionListener;
31 import org.eclipse.swt.graphics.Point;
32 import org.eclipse.swt.layout.GridData;
33 import org.eclipse.swt.layout.GridLayout;
34 import org.eclipse.swt.widgets.Button;
35 import org.eclipse.swt.widgets.Composite;
36 import org.eclipse.swt.widgets.Control;
37 import org.eclipse.swt.widgets.Display;
38 import org.eclipse.swt.widgets.Label;
39 import org.eclipse.swt.widgets.Shell;
40 import org.eclipse.swt.widgets.Text;
41 import org.eclipse.ui.IEditorPart;
42 import org.eclipse.ui.IWorkbenchPage;
43 import org.eclipse.ui.IWorkbenchPartSite;
44 import org.eclipse.ui.PlatformUI;
45 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
46 
47 import java.util.Collections;
48 import java.util.List;
49 
50 @SuppressWarnings("restriction") // WST DOM access
51 class LintListDialog extends TitleAreaDialog implements SelectionListener {
52     private static final String PROJECT_LOGO_LARGE = "icons/android-64.png"; //$NON-NLS-1$
53     private IFile mFile;
54     private Button mFixButton;
55     private Button mIgnoreButton;
56     private Button mShowButton;
57     private Text mDetailsText;
58     private Button mIgnoreTypeButton;
59     private LintList mList;
60 
LintListDialog(Shell parentShell, IFile file)61     LintListDialog(Shell parentShell, IFile file) {
62         super(parentShell);
63         this.mFile = file;
64     }
65 
66     @Override
setShellStyle(int newShellStyle)67     protected void setShellStyle(int newShellStyle) {
68         // Allow resize
69         super.setShellStyle(newShellStyle | SWT.TITLE | SWT.MODELESS | SWT.RESIZE);
70     }
71 
72     @Override
close()73     public boolean close() {
74         mList.dispose();
75         return super.close();
76     }
77 
78     @Override
createContents(Composite parent)79     protected Control createContents(Composite parent) {
80       Control contents = super.createContents(parent);
81       setTitle("Lint Warnings in Layout");
82       setMessage("Lint Errors found for the current layout:");
83       setTitleImage(AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE).createImage());
84       return contents;
85     }
86 
87     @SuppressWarnings("unused") // SWT constructors have side effects, they are not unused
88     @Override
createDialogArea(Composite parent)89     protected Control createDialogArea(Composite parent) {
90         Composite area = (Composite) super.createDialogArea(parent);
91         Composite container = new Composite(area, SWT.NONE);
92         container.setLayoutData(new GridData(GridData.FILL_BOTH));
93 
94         container.setLayout(new GridLayout(2, false));
95         IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
96         IWorkbenchPartSite site = null;
97         if (page.getActivePart() != null) {
98             site = page.getActivePart().getSite();
99         }
100         mList = new LintList(site, container, null /*memento*/, true /*singleFile*/);
101         mList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 5));
102 
103         mShowButton = new Button(container, SWT.NONE);
104         mShowButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
105         mShowButton.setText("Show");
106         mShowButton.addSelectionListener(this);
107 
108         mIgnoreButton = new Button(container, SWT.NONE);
109         mIgnoreButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
110         mIgnoreButton.setText("Ignore");
111         mIgnoreButton.setEnabled(false);
112         mIgnoreButton.addSelectionListener(this);
113 
114         mIgnoreTypeButton = new Button(container, SWT.NONE);
115         mIgnoreTypeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
116         mIgnoreTypeButton.setText("Ignore Type");
117         mIgnoreTypeButton.addSelectionListener(this);
118 
119         mFixButton = new Button(container, SWT.NONE);
120         mFixButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
121         mFixButton.setText("Fix");
122         mFixButton.setEnabled(false);
123         mFixButton.addSelectionListener(this);
124 
125         new Label(container, SWT.NONE);
126 
127         mDetailsText = new Text(container, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP
128                 | SWT.V_SCROLL | SWT.MULTI);
129         Display display = parent.getDisplay();
130         mDetailsText.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
131         mDetailsText.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
132         GridData gdText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
133         gdText.heightHint = 80;
134         mDetailsText.setLayoutData(gdText);
135 
136         new Label(container, SWT.NONE);
137 
138         mList.addSelectionListener(this);
139 
140         mList.setResources(Collections.<IResource>singletonList(mFile));
141         if (mList.getSelectedMarkers().size() > 0) {
142             updateSelectionState();
143         }
144 
145         return area;
146     }
147 
148     /**
149      * Create contents of the button bar.
150      */
151     @Override
createButtonsForButtonBar(Composite parent)152     protected void createButtonsForButtonBar(Composite parent) {
153         createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
154     }
155 
156     /**
157      * Return the initial size of the dialog.
158      */
159     @Override
getInitialSize()160     protected Point getInitialSize() {
161         return new Point(600, 400);
162     }
163 
selectMarker(IMarker marker)164     private void selectMarker(IMarker marker) {
165         if (marker == null) {
166             mDetailsText.setText(""); //$NON-NLS-1$
167             return;
168         }
169 
170         mDetailsText.setText(EclipseLintClient.describe(marker));
171     }
172 
173     // ---- Implements SelectionListener ----
174 
175     @Override
widgetSelected(SelectionEvent e)176     public void widgetSelected(SelectionEvent e) {
177         Object source = e.getSource();
178         if (source == mList.getTreeViewer().getControl()) {
179             // Enable/disable buttons
180             updateSelectionState();
181         } else if (source == mShowButton) {
182             List<IMarker> selection = mList.getSelectedMarkers();
183             if (selection.size() > 0) {
184                 EclipseLintClient.showMarker(selection.get(0));
185             }
186         } else if (source == mFixButton) {
187             List<IMarker> selection = mList.getSelectedMarkers();
188             for (IMarker marker : selection) {
189                 LintFix fix = LintFix.getFix(EclipseLintClient.getId(marker), marker);
190                 IEditorPart editor = AdtUtils.getActiveEditor();
191                 if (editor instanceof AndroidXmlEditor) {
192                     IStructuredDocument doc = ((AndroidXmlEditor) editor).getStructuredDocument();
193                     fix.apply(doc);
194                     if (fix.needsFocus()) {
195                         close();
196                     }
197                 } else {
198                     AdtPlugin.log(IStatus.ERROR, "Did not find associated editor to apply fix");
199                 }
200             }
201         } else if (source == mIgnoreTypeButton) {
202             for (IMarker marker : mList.getSelectedMarkers()) {
203                 String id = EclipseLintClient.getId(marker);
204                 if (id != null) {
205                     LintFixGenerator.suppressDetector(id, true, mFile, true /*all*/);
206                 }
207             }
208         }
209     }
210 
updateSelectionState()211     private void updateSelectionState() {
212         List<IMarker> selection = mList.getSelectedMarkers();
213 
214         if (selection.size() == 1) {
215             selectMarker(selection.get(0));
216         } else {
217             selectMarker(null);
218         }
219 
220         boolean canFix = selection.size() > 0;
221         for (IMarker marker : selection) {
222             if (!LintFix.hasFix(EclipseLintClient.getId(marker))) {
223                 canFix = false;
224                 break;
225             }
226 
227             // Some fixes cannot be run in bulk
228             if (selection.size() > 1) {
229                 LintFix fix = LintFix.getFix(EclipseLintClient.getId(marker), marker);
230                 if (!fix.isBulkCapable()) {
231                     canFix = false;
232                     break;
233                 }
234             }
235         }
236 
237         mFixButton.setEnabled(canFix);
238     }
239 
240     @Override
widgetDefaultSelected(SelectionEvent e)241     public void widgetDefaultSelected(SelectionEvent e) {
242         Object source = e.getSource();
243         if (source == mList.getTreeViewer().getControl()) {
244             // Jump to editor
245             List<IMarker> selection = mList.getSelectedMarkers();
246             if (selection.size() > 0) {
247                 EclipseLintClient.showMarker(selection.get(0));
248                 close();
249             }
250         }
251     }
252 }
253