/*
* FindBugs Eclipse Plug-in.
* Copyright (C) 2005, University of Maryland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Feb 7, 2005
*/
package de.tobject.findbugs.classify;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import de.tobject.findbugs.FindbugsPlugin;
import de.tobject.findbugs.reporter.MarkerUtil;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugProperty;
import edu.umd.cs.findbugs.config.UserPreferences;
/**
* Pulldown toolbar action for classifying a FindBugs warning as "bug" or
* "not a bug".
*
* @author David Hovemeyer
*/
public class AccuracyClassificationPulldownAction implements IWorkbenchWindowPulldownDelegate2 {
protected static boolean DEBUG;
private Menu menu;
private MenuItem isBugItem;
private MenuItem notBugItem;
private IMarker marker;
private BugInstance bugInstance;
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.IWorkbenchWindowPulldownDelegate2#getMenu(org.eclipse.
* swt.widgets.Menu)
*/
public Menu getMenu(Menu parent) {
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.IWorkbenchWindowPulldownDelegate#getMenu(org.eclipse.swt
* .widgets.Control)
*/
public Menu getMenu(Control parent) {
if (menu == null) {
menu = new Menu(parent);
fillMenu();
}
return menu;
}
/**
* Fill the classification menu.
*/
private void fillMenu() {
isBugItem = new MenuItem(menu, SWT.RADIO);
isBugItem.setText("Bug");
notBugItem = new MenuItem(menu, SWT.RADIO);
notBugItem.setText("Not Bug");
isBugItem.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
* .swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
if (bugInstance != null) {
classifyWarning(bugInstance, true);
}
}
});
notBugItem.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
* .swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
if (bugInstance != null) {
classifyWarning(bugInstance, false);
}
}
});
menu.addMenuListener(new MenuAdapter() {
@Override
public void menuShown(MenuEvent e) {
// Before showing the menu, sync its contents
// with the current BugInstance (if any)
if (DEBUG) {
System.out.println("Synchronizing menu!");
}
syncMenu();
}
});
}
private void classifyWarning(BugInstance warning, boolean isBug) {
BugProperty isBugProp = warning.lookupProperty(BugProperty.IS_BUG);
if (isBugProp != null) {
// Warning was previously classified
if (isBugProp.getValueAsBoolean() == isBug) {
// No change
return;
}
}
// Warning is being classified for the first time,
// or the classification is being changed
warning.setProperty(BugProperty.IS_BUG, isBug ? "true" : "false");
try {
FindbugsPlugin.markBugCollectionDirty(marker.getResource().getProject(), true);
} catch (CoreException e) {
FindbugsPlugin.getDefault().logException(e, "Could not mark bug collection dirty");
}
// Currently, we are displaying a marker for this warning.
// If the user has classified it as a false warning,
// and false warnings are not being displayed, then we can
// remove the marker.
if (!isBug) {
IProject project = marker.getResource().getProject();
try {
UserPreferences userPrefs = FindbugsPlugin.getUserPreferences(project);
if (!MarkerUtil.shouldDisplayWarning(warning, userPrefs.getFilterSettings())) {
if (DEBUG) {
System.out.println("Deleting marker for false warning!");
}
marker.delete();
}
} catch (CoreException e) {
FindbugsPlugin.getDefault().logException(e, "Could not get FindBugs preferences for project");
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
*/
public void dispose() {
if (menu != null) {
menu.dispose();
menu = null;
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.
* IWorkbenchWindow)
*/
public void init(IWorkbenchWindow window) {
// This just runs once when the action is created
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
public void run(IAction action) {
// TODO: we should create a "Classify Warning" dialog here.
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action
* .IAction, org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IAction action, ISelection selection) {
bugInstance = null;
// TODO learn to deal with ALL elements
IMarker markerFromSelection = MarkerUtil.getMarkerFromSingleSelection(selection);
marker = markerFromSelection;
if (marker == null) {
// No marker selected.
return;
}
if (DEBUG) {
System.out.println("Found a marker!");
}
bugInstance = MarkerUtil.findBugInstanceForMarker(marker);
if (bugInstance != null) {
if (DEBUG) {
System.out.println("Found BugInstance for FindBugs warning marker!");
}
}
}
/**
* Update menu to match currently selected BugInstance.
*/
private void syncMenu() {
if (bugInstance != null) {
isBugItem.setEnabled(true);
notBugItem.setEnabled(true);
BugProperty isBugProperty = bugInstance.lookupProperty(BugProperty.IS_BUG);
if (isBugProperty == null) {
// Unclassified
isBugItem.setSelection(false);
notBugItem.setSelection(false);
} else {
boolean isBug = isBugProperty.getValueAsBoolean();
isBugItem.setSelection(isBug);
notBugItem.setSelection(!isBug);
}
} else {
// No bug instance, so uncheck and disable the menu items
if (DEBUG) {
System.out.println("No bug instance found, disabling menu items");
}
isBugItem.setEnabled(false);
notBugItem.setEnabled(false);
isBugItem.setSelection(false);
notBugItem.setSelection(false);
}
}
}