diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintListDialog.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintListDialog.java | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintListDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintListDialog.java new file mode 100644 index 000000000..f88c3772c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintListDialog.java @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2011 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.lint; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.AdtUtils; +import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; +import com.android.ide.eclipse.adt.internal.editors.IconFactory; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@SuppressWarnings("restriction") // WST DOM access +class LintListDialog extends TitleAreaDialog implements SelectionListener { + private static final String PROJECT_LOGO_LARGE = "android-64"; //$NON-NLS-1$ + private final IFile mFile; + private final IEditorPart mEditor; + private Button mFixButton; + private Button mIgnoreButton; + private Button mIgnoreAllButton; + private Button mShowButton; + private Text mDetailsText; + private Button mIgnoreTypeButton; + private LintList mList; + + LintListDialog( + @NonNull Shell parentShell, + @NonNull IFile file, + @Nullable IEditorPart editor) { + super(parentShell); + mFile = file; + mEditor = editor; + setHelpAvailable(false); + } + + @Override + protected void setShellStyle(int newShellStyle) { + // Allow resize + super.setShellStyle(newShellStyle | SWT.TITLE | SWT.MODELESS | SWT.RESIZE); + } + + @Override + public boolean close() { + mList.dispose(); + return super.close(); + } + + @Override + protected Control createContents(Composite parent) { + Control contents = super.createContents(parent); + setTitle("Lint Warnings in Layout"); + setMessage("Lint Errors found for the current layout:"); + setTitleImage(IconFactory.getInstance().getIcon(PROJECT_LOGO_LARGE)); + + return contents; + } + + @SuppressWarnings("unused") // SWT constructors have side effects, they are not unused + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + Composite container = new Composite(area, SWT.NONE); + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + + container.setLayout(new GridLayout(2, false)); + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IWorkbenchPartSite site = null; + if (page.getActivePart() != null) { + site = page.getActivePart().getSite(); + } + + mList = new LintList(site, container, null /*memento*/, true /*singleFile*/); + mList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 6)); + + mShowButton = new Button(container, SWT.NONE); + mShowButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + mShowButton.setText("Show"); + mShowButton.setToolTipText("Opens the editor to reveal the XML with the issue"); + mShowButton.addSelectionListener(this); + + mFixButton = new Button(container, SWT.NONE); + mFixButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + mFixButton.setText("Fix"); + mFixButton.setToolTipText("Automatically corrects the problem, if possible"); + mFixButton.setEnabled(false); + mFixButton.addSelectionListener(this); + + mIgnoreButton = new Button(container, SWT.NONE); + mIgnoreButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + mIgnoreButton.setText("Suppress Issue"); + mIgnoreButton.setToolTipText("Adds a special attribute in the layout to suppress this specific warning"); + mIgnoreButton.addSelectionListener(this); + + mIgnoreAllButton = new Button(container, SWT.NONE); + mIgnoreAllButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + mIgnoreAllButton.setText("Suppress in Layout"); + mIgnoreAllButton.setEnabled(mEditor instanceof AndroidXmlEditor); + mIgnoreAllButton.setToolTipText("Adds an attribute on the root element to suppress all issues of this type in this layout"); + mIgnoreAllButton.addSelectionListener(this); + + mIgnoreTypeButton = new Button(container, SWT.NONE); + mIgnoreTypeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + mIgnoreTypeButton.setText("Disable Issue Type"); + mIgnoreTypeButton.setToolTipText("Turns off checking for this type of error everywhere"); + mIgnoreTypeButton.addSelectionListener(this); + + new Label(container, SWT.NONE); + + mDetailsText = new Text(container, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP + | SWT.V_SCROLL | SWT.MULTI); + Display display = parent.getDisplay(); + mDetailsText.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + mDetailsText.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + GridData gdText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1); + gdText.heightHint = 80; + mDetailsText.setLayoutData(gdText); + + new Label(container, SWT.NONE); + + mList.addSelectionListener(this); + + mList.setResources(Collections.<IResource>singletonList(mFile)); + mList.selectFirst(); + if (mList.getSelectedMarkers().size() > 0) { + updateSelectionState(); + } + + return area; + } + + /** + * Create contents of the button bar. + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + } + + /** + * Return the initial size of the dialog. + */ + @Override + protected Point getInitialSize() { + return new Point(600, 400); + } + + private void selectMarker(IMarker marker) { + if (marker == null) { + mDetailsText.setText(""); //$NON-NLS-1$ + return; + } + + mDetailsText.setText(EclipseLintClient.describe(marker)); + } + + // ---- Implements SelectionListener ---- + + @Override + public void widgetSelected(SelectionEvent e) { + Object source = e.getSource(); + if (source == mList.getTreeViewer().getControl()) { + // Enable/disable buttons + updateSelectionState(); + } else if (source == mShowButton) { + List<IMarker> selection = mList.getSelectedMarkers(); + if (selection.size() > 0) { + EclipseLintClient.showMarker(selection.get(0)); + } + } else if (source == mFixButton) { + List<IMarker> selection = mList.getSelectedMarkers(); + for (IMarker marker : selection) { + List<LintFix> fixes = LintFix.getFixes(EclipseLintClient.getId(marker), marker); + if (fixes == null) { + continue; + } + LintFix fix = fixes.get(0); + IEditorPart editor = AdtUtils.getActiveEditor(); + if (editor instanceof AndroidXmlEditor) { + IStructuredDocument doc = ((AndroidXmlEditor) editor).getStructuredDocument(); + fix.apply(doc); + if (fix.needsFocus()) { + close(); + } + } else { + AdtPlugin.log(IStatus.ERROR, "Did not find associated editor to apply fix"); + } + } + } else if (source == mIgnoreTypeButton) { + for (IMarker marker : mList.getSelectedMarkers()) { + String id = EclipseLintClient.getId(marker); + if (id != null) { + LintFixGenerator.suppressDetector(id, true, mFile, true /*all*/); + } + } + } else if (source == mIgnoreButton) { + for (IMarker marker : mList.getSelectedMarkers()) { + LintFixGenerator.addSuppressAnnotation(marker); + } + } else if (source == mIgnoreAllButton) { + Set<String> ids = new HashSet<String>(); + for (IMarker marker : mList.getSelectedMarkers()) { + String id = EclipseLintClient.getId(marker); + if (id != null && !ids.contains(id)) { + ids.add(id); + if (mEditor instanceof AndroidXmlEditor) { + AndroidXmlEditor editor = (AndroidXmlEditor) mEditor; + AddSuppressAttribute fix = AddSuppressAttribute.createFixForAll(editor, + marker, id); + if (fix != null) { + IStructuredDocument document = editor.getStructuredDocument(); + fix.apply(document); + } + } + } + } + mList.refresh(); + } + } + + private void updateSelectionState() { + List<IMarker> selection = mList.getSelectedMarkers(); + + if (selection.size() == 1) { + selectMarker(selection.get(0)); + } else { + selectMarker(null); + } + + boolean canFix = selection.size() > 0; + for (IMarker marker : selection) { + if (!LintFix.hasFix(EclipseLintClient.getId(marker))) { + canFix = false; + break; + } + + // Some fixes cannot be run in bulk + if (selection.size() > 1) { + List<LintFix> fixes = LintFix.getFixes(EclipseLintClient.getId(marker), marker); + if (fixes == null || !fixes.get(0).isBulkCapable()) { + canFix = false; + break; + } + } + } + + mFixButton.setEnabled(canFix); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + Object source = e.getSource(); + if (source == mList.getTreeViewer().getControl()) { + // Jump to editor + List<IMarker> selection = mList.getSelectedMarkers(); + if (selection.size() > 0) { + EclipseLintClient.showMarker(selection.get(0)); + close(); + } + } + } +} |