blob: 1448a192d4292c0d257cd54f71ac4fdd7dcd2fce [file] [log] [blame]
/*
* Copyright (c) 2011 Eike Stepper (Berlin, Germany) 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.releng.tasks.table;
import org.eclipse.emf.cdo.releng.tasks.Activator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.nebula.jface.gridviewer.GridTableViewer;
import org.eclipse.nebula.widgets.grid.Grid;
import org.eclipse.nebula.widgets.grid.GridColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;
/**
* @author Eike Stepper
*/
public class TaskTableView extends ViewPart
{
public static final String ID = "org.eclipse.emf.cdo.releng.tasks.table.TaskTableView"; //$NON-NLS-1$
private static final String SEARCH_LABEL = "search";
private TaskModel taskModel;
private GridTableViewer viewer;
private boolean searching;
private TaskSearchAction searchAction;
private TaskFilterAction showEnhancements;
private TaskFilterAction showAmbiguous;
private TaskFilterAction showBugs;
private TaskFilterAction showOpen;
private TaskFilterAction showFixed;
public TaskTableView()
{
}
@Override
public void createPartControl(Composite parent)
{
taskModel = new TaskModel();
Composite container = new Composite(parent, SWT.NONE);
container.setLayout(new FillLayout());
{
viewer = new GridTableViewer(container, SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
Grid table = viewer.getGrid();
table.setCellSelectionEnabled(true);
table.setHeaderVisible(true);
table.addMouseListener(new TaskMouseListener());
table.addKeyListener(new TaskKeyListener());
{
GridColumn column = new GridColumn(table, SWT.NONE);
column.setText("Summary");
column.setWidth(400);
}
for (Version version : taskModel.getVersions())
{
GridColumn column = new GridColumn(table, SWT.CENTER);
column.setText(version.toString());
column.setWidth(90);
}
viewer.setContentProvider(new TaskContentProvider());
viewer.setLabelProvider(new TaskLabelProvider());
viewer.setInput(taskModel);
// ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.RECREATE);
getViewSite().setSelectionProvider(viewer);
}
createActions();
initializeToolBar();
initializeMenu();
viewer.setFilters(new ViewerFilter[] { new TaskViewerFilter() });
}
@Override
public void setFocus()
{
viewer.getControl().setFocus();
}
@Override
public void dispose()
{
if (taskModel != null)
{
taskModel.dispose();
taskModel = null;
}
super.dispose();
}
private void createActions()
{
}
private void initializeToolBar()
{
IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager();
toolbarManager.add(searchAction = new TaskSearchAction());
toolbarManager.add(new Separator());
toolbarManager.add(showEnhancements = new TaskFilterAction("Enhancements", "green.gif"));
toolbarManager.add(showBugs = new TaskFilterAction("Bugs", "red.gif"));
toolbarManager.add(showAmbiguous = new TaskFilterAction("Ambiguous", "yellow.gif"));
toolbarManager.add(new Separator());
toolbarManager.add(showOpen = new TaskFilterAction("Open", "open.gif"));
toolbarManager.add(showFixed = new TaskFilterAction("Fixed", "fixed.gif", false));
toolbarManager.add(new Separator());
toolbarManager.add(new TaskRefreshAction());
}
private void initializeMenu()
{
// IMenuManager menuManager = getViewSite().getActionBars().getMenuManager();
}
/**
* @author Eike Stepper
*/
private final class TaskViewerFilter extends ViewerFilter
{
@Override
public boolean select(Viewer viewer, Object parentElement, Object element)
{
LogicalTask task = (LogicalTask)element;
if (searching)
{
String filter = searchAction.getText().toLowerCase();
String summary = task.getSummary().toLowerCase();
if (summary.indexOf(filter) == -1)
{
return false;
}
}
int severityType = task.getSeverityType();
if (!showEnhancements.isChecked() && severityType == 1)
{
return false;
}
if (!showBugs.isChecked() && severityType == 2)
{
return false;
}
if (!showAmbiguous.isChecked() && severityType == 3)
{
return false;
}
boolean allFixed = task.isAllFixed();
if (!showOpen.isChecked() && !allFixed)
{
return false;
}
if (!showFixed.isChecked() && allFixed)
{
return false;
}
return true;
}
}
/**
* @author Eike Stepper
*/
private final class TaskSearchAction extends Action
{
public TaskSearchAction()
{
super(SEARCH_LABEL);
}
@Override
public void run()
{
MessageDialog.openInformation(getSite().getShell(), "Search Tasks",
"To search for tasks just start typing in the table.\nPress ESC to reset the search filter.");
}
}
/**
* @author Eike Stepper
*/
private final class TaskFilterAction extends Action
{
public TaskFilterAction(String text, String image, boolean checked)
{
super(text, IAction.AS_CHECK_BOX);
setImageDescriptor(Activator.getImageDescriptor("icons/" + image));
setChecked(checked);
}
public TaskFilterAction(String text, String image)
{
this(text, image, true);
}
@Override
public void run()
{
viewer.refresh(true);
}
}
/**
* @author Eike Stepper
*/
private final class TaskRefreshAction extends Action
{
public TaskRefreshAction()
{
super("Refresh", Activator.getImageDescriptor("icons/refresh.gif"));
}
@Override
public void run()
{
new Job("Refreshing")
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
taskModel.refresh();
viewer.getControl().getDisplay().syncExec(new Runnable()
{
public void run()
{
viewer.refresh(true);
}
});
return Status.OK_STATUS;
}
}.schedule();
}
}
/**
* @author Eike Stepper
*/
private final class TaskKeyListener extends KeyAdapter
{
@Override
public void keyPressed(KeyEvent e)
{
char c = e.character;
if (Character.isLetter(c) || Character.isDigit(c) || Character.isSpaceChar(c))
{
String filter = searchAction.getText().toLowerCase();
if (!searching)
{
filter = "";
searching = true;
}
filter += new Character(c);
searchAction.setText(filter.toLowerCase());
viewer.refresh(true);
}
else if (e.keyCode == SWT.BS)
{
if (searching)
{
String filter = searchAction.getText().toLowerCase();
searchAction.setText(filter.substring(0, filter.length() - 1));
viewer.refresh(true);
}
}
else if (e.keyCode == SWT.ESC)
{
searching = false;
searchAction.setText(SEARCH_LABEL);
viewer.refresh(true);
}
}
}
/**
* @author Eike Stepper
*/
private final class TaskMouseListener extends MouseAdapter
{
@Override
@SuppressWarnings("restriction")
public void mouseDoubleClick(MouseEvent event)
{
Object element = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
if (element instanceof LogicalTask)
{
LogicalTask logicalTask = (LogicalTask)element;
ViewerCell cell = viewer.getCell(new Point(event.x, event.y));
int columnIndex = cell.getColumnIndex();
if (columnIndex != 0)
{
Version[] versions = taskModel.getVersions();
Version version = versions[columnIndex - 1];
for (VersionTask versionTask : logicalTask.getVersionTasks())
{
if (versionTask.getVersion().equals(version))
{
ITask task = versionTask.getTask();
org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal.refreshAndOpenTaskListElement(task);
}
}
}
}
}
}
/**
* @author Eike Stepper
*/
private final class TaskContentProvider implements IStructuredContentProvider
{
public Object[] getElements(Object inputElement)
{
return taskModel.getLogicalTasks();
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
}
public void dispose()
{
}
}
/**
* @author Eike Stepper
*/
private final class TaskLabelProvider extends CellLabelProvider
{
private Color gray = viewer.getControl().getDisplay().getSystemColor(SWT.COLOR_GRAY);
private Color red = viewer.getControl().getDisplay().getSystemColor(SWT.COLOR_RED);
private Font bold = getBoldFont();
private Image[] severityImages = { null, loadImage("green.gif"), loadImage("red.gif"), loadImage("yellow.gif") };
@Override
public void update(ViewerCell cell)
{
LogicalTask logicalTask = (LogicalTask)cell.getElement();
int columnIndex = cell.getColumnIndex();
if (columnIndex == 0)
{
cell.setImage(severityImages[logicalTask.getSeverityType()]);
cell.setText(logicalTask.getSummary());
cell.setFont(logicalTask.getSeverityType() > 1 ? bold : null);
cell.setForeground(logicalTask.isAllFixed() ? gray : null);
}
else
{
Version version = taskModel.getVersions()[columnIndex - 1];
VersionTask versionTask = logicalTask.getVersionTask(version);
if (versionTask != null)
{
cell.setText(versionTask.getStatus());
cell.setFont(!"enhancement".equalsIgnoreCase(versionTask.getSeverity()) ? bold : null);
cell.setForeground("FIXED".equalsIgnoreCase(versionTask.getResolution()) ? gray : null);
cell.setBackground(logicalTask.getVersionTaskCount(version) > 1 ? red : null);
}
else
{
cell.setText("");
cell.setFont(null);
cell.setForeground(null);
cell.setBackground(null);
}
}
}
@Override
public String getToolTipText(Object element)
{
return super.getToolTipText(element);
}
@Override
public Point getToolTipShift(Object object)
{
return new Point(5, 5);
}
@Override
public int getToolTipDisplayDelayTime(Object object)
{
return 500;
}
@Override
public int getToolTipTimeDisplayed(Object object)
{
return 4000;
}
@Override
public void dispose()
{
if (bold != null)
{
bold.dispose();
bold = null;
}
for (int i = 0; i < severityImages.length; i++)
{
if (severityImages[i] != null)
{
severityImages[i].dispose();
severityImages[i] = null;
}
}
super.dispose();
}
private Image loadImage(String file)
{
ImageDescriptor descriptor = Activator.getImageDescriptor("icons/" + file);
return descriptor.createImage(viewer.getControl().getDisplay());
}
public Font getBoldFont()
{
Control control = viewer.getControl();
FontData[] datas = control.getFont().getFontData().clone();
datas[0].setStyle(SWT.BOLD);
Display display = control.getShell().getDisplay();
Font font = new Font(display, datas);
return font;
}
}
}