blob: 90fb40740392d5496491a4d194963d6728fd241a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2009 Tasktop Technologies 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:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.sandbox.ui.views;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.mylyn.commons.ui.compatibility.CommonThemes;
import org.eclipse.mylyn.internal.sandbox.ui.planner.ActivityReportAction;
import org.eclipse.mylyn.internal.sandbox.ui.planner.TaskActivityLabelProvider;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.DateRange;
import org.eclipse.mylyn.internal.tasks.core.ITaskListChangeListener;
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.TaskContainerDelta;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.actions.OpenTaskListElementAction;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskActivationListener;
import org.eclipse.mylyn.tasks.core.ITaskContainer;
import org.eclipse.mylyn.tasks.core.TaskActivationAdapter;
import org.eclipse.mylyn.tasks.ui.TaskElementLabelProvider;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.themes.IThemeManager;
/**
* @author Rob Elves
*/
public class TaskActivityView extends ViewPart {
private static final String MEMENTO_KEY_WIDTH = "colwidth";
public static final String ID = "org.eclipse.mylyn.tasklist.activity";
public static final String columnWidthIdentifier = "org.eclipse.mylyn.tasklist.ui.views.taskactivity.columnwidth";
public static final String tableSortIdentifier = "org.eclipse.mylyn.tasklist.ui.views.taskactivity.sortIndex";
private static TaskActivityView INSTANCE;
private IMemento taskActivityMemento;
private OpenTaskListElementAction openTaskEditor;
private final String[] columnNames = new String[] { " ", " !", "Description", "Elapsed", "Estimated", "Scheduled",
/*"Last Active"*/};
private final String[] ESTIMATE_TIMES = new String[] { "0 Hours", "1 Hours", "2 Hours", "3 Hours", "4 Hours",
"5 Hours", "6 Hours", "7 Hours", "8 Hours", "9 Hours", "10 Hours" };
private final int[] columnWidths = new int[] { 60, 12, 160, 60, 70, 100 /*, 100*/};
private TreeColumn[] columns;
private TaskActivityLabelProvider taskHistoryTreeLabelProvider;
private TreeViewer treeViewer;
private TaskActivityViewContentProvider taskActivityTableContentProvider;
// private TaskScheduleContentProvider taskActivityTableContentProvider;
private IThemeManager themeManager;
private final IPropertyChangeListener THEME_CHANGE_LISTENER = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(IThemeManager.CHANGE_CURRENT_THEME)
|| event.getProperty().equals(CommonThemes.COLOR_CATEGORY)) {
taskHistoryTreeLabelProvider.setCategoryBackgroundColor(themeManager.getCurrentTheme()
.getColorRegistry()
.get(CommonThemes.COLOR_CATEGORY));
refresh();
}
}
};
/**
* TODO: need lazier refresh policy.
*/
private final ITaskActivationListener TASK_ACTIVATION_LISTENER = new TaskActivationAdapter() {
@Override
public void taskActivated(ITask task) {
refresh();
}
};
private final ITaskListChangeListener TASKLIST_CHANGE_LISTENER = new ITaskListChangeListener() {
public void containersChanged(Set<TaskContainerDelta> containers) {
refresh();
}
};
private TaskActivityViewSorter sorter;
public static TaskActivityView openInActivePerspective() {
try {
return (TaskActivityView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(ID);
} catch (Exception e) {
return null;
}
}
public TaskActivityView() {
INSTANCE = this;
TasksUi.getTaskActivityManager().addActivationListener(TASK_ACTIVATION_LISTENER);
TasksUiInternal.getTaskList().addChangeListener(TASKLIST_CHANGE_LISTENER);
}
@Override
public void dispose() {
super.dispose();
TasksUi.getTaskActivityManager().removeActivationListener(TASK_ACTIVATION_LISTENER);
TasksUiInternal.getTaskList().removeChangeListener(TASKLIST_CHANGE_LISTENER);
}
@Override
public void createPartControl(Composite parent) {
themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
themeManager.addPropertyChangeListener(THEME_CHANGE_LISTENER);
int treeStyle = SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;
treeViewer = new TreeViewer(parent, treeStyle);
getViewer().getTree().setHeaderVisible(true);
getViewer().getTree().setLinesVisible(true);
getViewer().setColumnProperties(columnNames);
getViewer().setUseHashlookup(true);
columns = new TreeColumn[columnNames.length];
for (int i = 0; i < columnNames.length; i++) {
columns[i] = new TreeColumn(getViewer().getTree(), SWT.LEFT);
columns[i].setText(columnNames[i]);
columns[i].setWidth(columnWidths[i]);
final int index = i;
columns[i].addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
int column = index - 1;
if (column == sorter.getSortColumn()) {
sorter.reverseDirection();
} else {
sorter.setSortColumn(column);
}
getViewer().refresh();
// if(taskActivityMemento != null) {
// sorter.saveState(taskActivityMemento);
// }
}
});
columns[i].addControlListener(new ControlListener() {
public void controlResized(ControlEvent e) {
for (int j = 0; j < columnWidths.length; j++) {
if (columns[j].equals(e.getSource())) {
columnWidths[j] = columns[j].getWidth();
}
}
}
public void controlMoved(ControlEvent e) {
// don't care if the control is moved
}
});
}
IThemeManager themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
Color categoryBackground = themeManager.getCurrentTheme().getColorRegistry().get(CommonThemes.COLOR_CATEGORY);
sorter = new TaskActivityViewSorter();
getViewer().setSorter(sorter);
taskActivityTableContentProvider = new TaskActivityViewContentProvider(TasksUiPlugin.getTaskActivityManager());
taskHistoryTreeLabelProvider = new TaskActivityLabelProvider(new TaskElementLabelProvider(false),
PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(), categoryBackground,
taskActivityTableContentProvider);
getViewer().setContentProvider(taskActivityTableContentProvider);
getViewer().setLabelProvider(taskHistoryTreeLabelProvider);
getViewer().setInput(getViewSite());
restoreState();
createCellEditorListener();
makeActions();
initDrop();
hookOpenAction();
hookContextMenu();
contributeToActionBars();
getSite().setSelectionProvider(getViewer());
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(new ActivityReportAction());
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void initDrop() {
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
treeViewer.addDropSupport(DND.DROP_MOVE, types, new ViewerDropAdapter(treeViewer) {
{
setFeedbackEnabled(false);
}
@Override
public boolean performDrop(Object data) {
IStructuredSelection selection = ((IStructuredSelection) TaskListView.getFromActivePerspective()
.getViewer()
.getSelection());
Object target = getCurrentTarget();
ScheduledTaskContainer container;
DateRange reminderCalendar;
if (target instanceof ScheduledTaskContainer) {
container = (ScheduledTaskContainer) target;
reminderCalendar = container.getDateRange();
} else if (target instanceof ITask) {
reminderCalendar = ((AbstractTask) target).getScheduledForDate();
} else {
return false;
}
for (Iterator<?> iter = selection.iterator(); iter.hasNext();) {
Object selectedObject = iter.next();
AbstractTask task = null;
if (selectedObject instanceof ITask) {
task = (AbstractTask) selectedObject;
}
if (task != null) {
TasksUiPlugin.getTaskActivityManager().setScheduledFor(task, reminderCalendar);
}
}
return true;
}
@Override
public boolean validateDrop(Object targetObject, int operation, TransferData transferType) {
Object selectedObject = ((IStructuredSelection) TaskListView.getFromActivePerspective()
.getViewer()
.getSelection()).getFirstElement();
if (selectedObject instanceof ITaskContainer) {
return false;
}
Object target = getCurrentTarget();
ScheduledTaskContainer dateRangeContainer = null;
if (target instanceof ScheduledTaskContainer) {
dateRangeContainer = (ScheduledTaskContainer) target;
} else if (target instanceof ITask) {
AbstractTask task = ((AbstractTask) target);
dateRangeContainer = new ScheduledTaskContainer(TasksUiPlugin.getTaskActivityManager(),
task.getScheduledForDate());
}
if (dateRangeContainer != null && (dateRangeContainer.isPresent() || dateRangeContainer.isFuture())) {
return true;
}
return false;
}
});
}
private void makeActions() {
openTaskEditor = new OpenTaskListElementAction();
getViewer().addSelectionChangedListener(openTaskEditor);
// openUrlInExternal = new OpenTaskInExternalBrowserAction();
}
private void hookOpenAction() {
getViewer().addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
openTaskEditor.run();
}
});
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
TaskActivityView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(getViewer().getControl());
getViewer().getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, getViewer());
}
private void fillContextMenu(IMenuManager manager) {
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
public static TaskActivityView getDefault() {
return INSTANCE;
}
private TreeViewer getViewer() {
return treeViewer;
}
private void refresh() {
if (PlatformUI.getWorkbench() != null && !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
if (getViewer().getControl() != null && !getViewer().getControl().isDisposed()) {
TaskActivityView.this.treeViewer.refresh();
}
}
});
}
}
public ITask getSelectedTask() {
ISelection selection = getViewer().getSelection();
if (selection.isEmpty()) {
return null;
}
if (selection instanceof StructuredSelection) {
StructuredSelection structuredSelection = (StructuredSelection) selection;
Object element = structuredSelection.getFirstElement();
if (element instanceof ITask) {
return (ITask) structuredSelection.getFirstElement();
}
}
return null;
}
@Override
public void setFocus() {
// ignore
}
private void createCellEditorListener() {
CellEditor[] editors = new CellEditor[columnNames.length];
final ComboBoxCellEditor estimateEditor = new ComboBoxCellEditor(treeViewer.getTree(), ESTIMATE_TIMES,
SWT.READ_ONLY);
// final ReminderCellEditor reminderEditor = new ReminderCellEditor(treeViewer.getTree());
editors[0] = null; // not used
editors[1] = null;// not used
editors[2] = null;// not used
editors[3] = null;// not used
editors[4] = estimateEditor;
editors[5] = null;//reminderEditor;
// reminderEditor.addListener(new ICellEditorListener() {
// public void applyEditorValue() {
// Object selection = ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
// if (selection instanceof ITask) {
// Date newReminder = reminderEditor.getReminderDate();
// if (newReminder != null) {
// TasksUiPlugin.getTaskActivityManager().setScheduledFor(
// dateRangeActivityDelegate.getCorrespondingTask(), newReminder);
// }
// }
// }
//
// public void cancelEditor() {
// }
//
// public void editorValueChanged(boolean oldValidState, boolean newValidState) {
// }
//
// });
estimateEditor.addListener(new ICellEditorListener() {
public void applyEditorValue() {
Object selection = ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
if (selection instanceof AbstractTask) {
AbstractTask task = (AbstractTask) selection;
int estimate = (Integer) estimateEditor.getValue();
if (estimate == -1) {
estimate = 0;
}
task.setEstimatedTimeHours(estimate);
refresh();
}
}
public void cancelEditor() {
}
public void editorValueChanged(boolean oldValidState, boolean newValidState) {
}
});
treeViewer.setCellEditors(editors);
getViewer().setCellModifier(new TaskActivityCellModifier(treeViewer));
}
private class TaskActivityCellModifier implements ICellModifier {
private final TreeViewer treeViewer;
public TaskActivityCellModifier(TreeViewer tableViewer) {
this.treeViewer = tableViewer;
}
public boolean canModify(Object element, String property) {
if (element instanceof ITask) {
int columnIndex = Arrays.asList(columnNames).indexOf(property);
if (columnIndex == 4 /*|| columnIndex == 5*/) {
return true;
}
}
return false;
}
public Object getValue(Object element, String property) {
if (element instanceof ITask) {
AbstractTask task = (AbstractTask) element;
int columnIndex = Arrays.asList(columnNames).indexOf(property);
/*if (columnIndex == 5) {
if (task.getScheduledForDate() != null) {
return DateFormat.getDateInstance(DateFormat.MEDIUM).format(task.getScheduledForDate());
} else {
return null;
}
} else*/if (columnIndex == 4) {
return new Integer(Arrays.asList(ESTIMATE_TIMES).indexOf(task.getEstimatedTimeHours()));
}
}
return null;
}
public void modify(Object element, String property, Object value) {
int columnIndex = Arrays.asList(columnNames).indexOf(property);
if (element instanceof AbstractTask) {
AbstractTask task = (AbstractTask) element;
if (columnIndex == 4) {
if (value instanceof Integer) {
task.setEstimatedTimeHours(((Integer) value).intValue() * 10);
treeViewer.refresh();
}
}
}
}
}
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
this.taskActivityMemento = memento;
}
@Override
public void saveState(IMemento memento) {
IMemento colMemento = memento.createChild(columnWidthIdentifier);
for (int i = 0; i < columnWidths.length; i++) {
IMemento m = colMemento.createChild("col" + i);
m.putInteger(MEMENTO_KEY_WIDTH, columnWidths[i]);
}
sorter.saveState(memento);
}
private void restoreState() {
if (taskActivityMemento != null) {
IMemento taskActivityWidth = taskActivityMemento.getChild(columnWidthIdentifier);
if (taskActivityWidth != null) {
for (int i = 0; i < columnWidths.length; i++) {
IMemento m = taskActivityWidth.getChild("col" + i);
if (m != null) {
int width = m.getInteger(MEMENTO_KEY_WIDTH);
columnWidths[i] = width;
columns[i].setWidth(width);
}
}
}
sorter.restoreState(taskActivityMemento);
}
getViewer().refresh();
}
}