/*******************************************************************************
* Copyright (c) 2012, 2014 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
* Marc Dumais (Ericsson) - Re-factored (bug 432908)
*******************************************************************************/
package org.eclipse.cdt.visualizer.examples.problemvisualizer;
import java.util.List;
import org.eclipse.cdt.visualizer.ui.canvas.GraphicCanvas;
import org.eclipse.cdt.visualizer.ui.canvas.GraphicCanvasVisualizer;
import org.eclipse.cdt.visualizer.ui.canvas.VirtualBoundsGraphicObject;
import org.eclipse.cdt.visualizer.ui.util.Colors;
import org.eclipse.cdt.visualizer.ui.util.SelectionManager;
import org.eclipse.cdt.visualizer.ui.util.SelectionUtils;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
public class ProblemVisualizer extends GraphicCanvasVisualizer {
/** The predefined number of severities */
private static final int NUM_SEVERITY = 3;
private static final Color MAIN_BACKGROUND_COLOR = Colors.WHITE;
private static final Color MAIN_FOREGROUND_COLOR = Colors.BLACK;
/** Virtual bounds of the "box" that will contains the bars */
private static final int[] BAR_CONTAINER_BOUNDS = { 0, 0, 1, 18 };
private static final int BAR_VIRTUAL_WIDTH = 1;
private static final int BAR_VIRTUAL_HEIGHT = 4;
/** Virtual bounds of each of the bars, relative to their container */
private static final int[][] BARS_VIRTUAL_BOUNDS = {
{ 0, 13, BAR_VIRTUAL_WIDTH, BAR_VIRTUAL_HEIGHT }, // infos
{ 0, 7, BAR_VIRTUAL_WIDTH, BAR_VIRTUAL_HEIGHT }, // warnings
{ 0, 1, BAR_VIRTUAL_WIDTH, BAR_VIRTUAL_HEIGHT } // errors
};
/** The canvas on which we'll draw our bars */
private GraphicCanvas m_canvas;
/** Graphic container object - will hold the 3 bars */
private VirtualBoundsGraphicObject m_container = null;
/**
* The model containing the data to be displayed.
* In this case, it is the number of the three
* different types of problem markers.
*/
private int[] m_markerCount = new int[NUM_SEVERITY];
/** Labels for the different marker severity levels*/
private String[] m_markerSeverityLabels = {
Messages.ProblemCountVisualizer_Infos,
Messages.ProblemCountVisualizer_Warnings,
Messages.ProblemCountVisualizer_Errors,
};
public ProblemVisualizer() {
super(Messages.ProblemCountVisualizer_Name,
Messages.ProblemCountVisualizer_DisplayName,
Messages.ProblemCountVisualizer_Description);
}
@Override
public GraphicCanvas createCanvas(Composite parent) {
m_canvas = new ResizableGraphicCanvas(this, parent);
return m_canvas;
}
@Override
protected void initializeCanvas(GraphicCanvas canvas) {
m_canvas.setBackground(MAIN_BACKGROUND_COLOR);
m_canvas.setForeground(MAIN_FOREGROUND_COLOR);
}
@Override
public void disposeCanvas()
{
if (m_canvas != null) {
m_canvas.dispose();
m_canvas = null;
}
}
@Override
public void visualizerDeselected() {
}
@Override
public void visualizerSelected() {
}
/**
* Actually create the graphics bars for the different severities.
* @param outline Should the bars be created, or the bar outline
* @return The bars to be drawn.
*/
private void createBars() {
BarGraphicObject bar;
// Graphic container that will contain the bars
m_container = new VirtualBoundsGraphicObject();
m_container.setVirtualBounds(BAR_CONTAINER_BOUNDS);
// no need to draw the ontainer's bounds
m_container.setDrawContainerBounds(false);
// The inside of the bars use a proportional width with the maximum width and
// the largest amount of markers for one severity.
// Find the maximum marker count to dictate the width
int maxCount = Math.max(m_markerCount[0], m_markerCount[1]);
maxCount = Math.max(maxCount, m_markerCount[2]);
if (maxCount == 0) maxCount = 1; // Set to anything but 0. It will be multiplied by 0 and not matter.
// go from high severity to low
for (int severity = IMarker.SEVERITY_ERROR; severity >= IMarker.SEVERITY_INFO; severity--) {
float barPercent = m_markerCount[severity] / (float) maxCount * 100.0f;
bar = new BarGraphicObject(severity, Math.round(barPercent));
bar.setVirtualBounds(BARS_VIRTUAL_BOUNDS[severity]);
bar.setLabel(m_markerSeverityLabels[severity] + " " + m_markerCount[severity]); //$NON-NLS-1$
m_container.addChildObject("bar" + severity, bar); //$NON-NLS-1$
}
// set real bounds on parent "container" object - real bounds of
// bars will be recursively computed in proportion of their virtual
// bounds, relative to their container
m_container.setBounds(m_canvas.getBounds());
// Add container object to canvas - when canvas draws the container,
// the bars will automatically be drawn too, so no need to add them
// to canvas.
m_canvas.add(m_container);
}
/**
* Clear the marker count array.
*/
private void clearMarkerCount() {
m_markerCount[IMarker.SEVERITY_ERROR] = 0;
m_markerCount[IMarker.SEVERITY_WARNING] = 0;
m_markerCount[IMarker.SEVERITY_INFO] = 0;
}
/**
* Add the count of problem markers for each severity for the
* specified resource.
*/
private void addToMarkerCount(IResource resource) {
IMarker[] problems = null;
try {
problems = resource.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
} catch (CoreException e) {
return;
}
for (IMarker problem : problems) {
try {
Object attrValue = problem.getAttribute(IMarker.SEVERITY);
if (attrValue != null && attrValue instanceof Integer) {
int severity = (Integer)attrValue;
m_markerCount[severity]++;
}
} catch (CoreException e) {
}
}
}
/**
* Refresh the visualizer display based on the existing data.
*/
public void refresh() {
m_canvas.clear();
// First create the outline bars
createBars();
m_canvas.add(m_container);
m_canvas.redraw();
}
@Override
public int handlesSelection(ISelection selection) {
List<Object> selections = SelectionUtils.getSelectedObjects(selection);
// As long as we support at least one element of the selection
// that is good enough
for (Object sel : selections) {
if (sel instanceof IResource) {
return 2;
}
}
return 0;
}
@Override
public void workbenchSelectionChanged(ISelection selection) {
clearMarkerCount();
List<Object> selections = SelectionUtils.getSelectedObjects(selection);
for (Object sel : selections) {
if (sel instanceof IResource) {
// Update the data
addToMarkerCount((IResource)sel);
}
}
refresh();
}
public SelectionManager getSelectionManager() {
return m_selectionManager;
}
}