/*******************************************************************************
* Copyright (c) 2011 Research Group for Industrial Software (INSO), Vienna University of Technology.
* 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:
* Research Group for Industrial Software (INSO), Vienna University of Technology - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.versions.tasks.ui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskContainer;
import org.eclipse.mylyn.versions.core.ChangeSet;
import org.eclipse.mylyn.versions.tasks.core.IChangeSetMapping;
import org.eclipse.mylyn.versions.tasks.core.TaskChangeSet;
import org.eclipse.mylyn.versions.tasks.ui.AbstractChangesetMappingProvider;
import org.eclipse.mylyn.versions.tasks.ui.TaskChangesetUtil;
import org.eclipse.mylyn.versions.tasks.ui.spi.ITaskVersionsContributionAction;
import org.eclipse.mylyn.versions.tasks.ui.spi.ITaskVersionsModel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
/**
* @author Kilian Matt
*/
@SuppressWarnings("restriction")
public class ChangesetPart extends AbstractFormPart {
private TableViewer table;
private final ChangesetModel model = new ChangesetModel();
private ChangeSetPage page;
public Control createControl(Composite parent, FormToolkit toolkit) {
Section createSection = createSection(parent, toolkit);
Composite composite = createContentComposite(toolkit, createSection);
createTable(composite);
return createSection;
}
@Override
public void initialize(IManagedForm form) {
super.initialize(form);
}
public void initialize(ChangeSetPage page) {
this.page = page;
}
private Composite createContentComposite(FormToolkit toolkit, Section createSection) {
Composite composite = toolkit.createComposite(createSection);
createSection.setClient(composite);
composite.setLayout(new FillLayout());
return composite;
}
private Section createSection(Composite parent, FormToolkit toolkit) {
Section createSection = toolkit.createSection(parent, ExpandableComposite.TITLE_BAR
| ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
createSection.setText("Changesets");
GridLayout gl = new GridLayout(1, false);
gl.marginBottom = 16;
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.horizontalSpan = 4;
createSection.setLayout(gl);
createSection.setLayoutData(gd);
addToolBar(toolkit, createSection);
return createSection;
}
private void createTable(Composite composite) {
table = new TableViewer(composite);
table.getTable().setLinesVisible(true);
table.getTable().setHeaderVisible(true);
addColumn(table, "Id");
addColumn(table, "Message");
addColumn(table, "Author");
addColumn(table, "Date");
table.setContentProvider(ArrayContentProvider.getInstance());
table.setLabelProvider(new TaskChangesetLabelProvider());
refreshInput();
registerContextMenu(table);
}
private void addToolBar(FormToolkit toolkit, Section section) {
ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
fillToolBar(toolBarManager);
if (toolBarManager.getSize() == 0) {
return;
}
Composite toolbarComposite = toolkit.createComposite(section);
toolbarComposite.setBackground(null);
RowLayout rowLayout = new RowLayout();
rowLayout.marginLeft = 0;
rowLayout.marginRight = 0;
rowLayout.marginTop = 0;
rowLayout.marginBottom = 0;
rowLayout.center = true;
toolbarComposite.setLayout(rowLayout);
toolBarManager.createControl(toolbarComposite);
section.clientVerticalSpacing = 0;
section.descriptionVerticalSpacing = 0;
section.setTextClient(toolbarComposite);
}
private void fillToolBar(ToolBarManager toolBarManager) {
toolBarManager.add(new IncludeSubTasksAction(model));
List<ITaskVersionsContributionAction> contributions = InternalExtensionPointLoader.loadActionContributions();
for (final ITaskVersionsContributionAction action : contributions) {
toolBarManager.add(new ActionDelegate(action) {
@Override
public void runWithEvent(Event event) {
action.run(model);
}
});
}
}
private void registerContextMenu(TableViewer table) {
MenuManager menuManager = new MenuManager();
menuManager.setRemoveAllWhenShown(true);
getPage().getEditorSite()
.registerContextMenu("org.eclipse.mylyn.versions.changesets", menuManager, table, true);
Menu menu = menuManager.createContextMenu(table.getControl());
table.getTable().setMenu(menu);
}
private void addColumn(TableViewer table, String name) {
TableViewerColumn tableViewerColumn = new TableViewerColumn(table, SWT.LEFT);
tableViewerColumn.getColumn().setText(name);
tableViewerColumn.getColumn().setWidth(100);
}
private AbstractChangesetMappingProvider determineBestProvider(final ITask task) {
AbstractChangesetMappingProvider bestProvider = new NullProvider();
int score = Integer.MIN_VALUE;
for (AbstractChangesetMappingProvider mappingProvider : TaskChangesetUtil.getMappingProviders()) {
if (score < mappingProvider.getScoreFor(task)) {
bestProvider = mappingProvider;
}
}
return bestProvider;
}
private static class NullProvider extends AbstractChangesetMappingProvider {
@Override
public void getChangesetsForTask(IChangeSetMapping mapping, IProgressMonitor monitor) throws CoreException {
}
@Override
public int getScoreFor(ITask task) {
return 0;
}
}
private IChangeSetMapping createChangeSetMapping(final ITask task, final List<TaskChangeSet> changesets) {
return new IChangeSetMapping() {
public ITask getTask() {
return task;
}
public void addChangeSet(ChangeSet changeset) {
changesets.add(new TaskChangeSet(task, changeset));
}
};
}
private void refreshInput() {
table.setInput(model.getInput());
}
private class ChangesetModel implements ITaskVersionsModel {
private boolean includeSubTasks;
public void setIncludeSubTasks(boolean includeSubTasks) {
boolean isChanged = this.includeSubTasks ^ includeSubTasks;
this.includeSubTasks = includeSubTasks;
if (isChanged) {
refreshInput();
}
}
public List<TaskChangeSet> getInput() {
final ITask task = getPage().getTask();
AbstractChangesetMappingProvider bestProvider = determineBestProvider(task);
final List<TaskChangeSet> changesets = new ArrayList<TaskChangeSet>();
final List<IChangeSetMapping> changesetsMapping = new ArrayList<IChangeSetMapping>();
changesetsMapping.add(createChangeSetMapping(task, changesets));
;
if (includeSubTasks) {
if (task instanceof ITaskContainer) {
ITaskContainer taskContainer = (ITaskContainer) task;
for (ITask subTask : taskContainer.getChildren()) {
changesetsMapping.add(createChangeSetMapping(subTask, changesets));
}
}
}
final AbstractChangesetMappingProvider provider = bestProvider;
BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
public void run() {
try {
for (IChangeSetMapping csm : changesetsMapping) {
provider.getChangesetsForTask(csm, new NullProgressMonitor());
}
} catch (CoreException e) {
}
}
});
return changesets;
}
}
private ChangeSetPage getPage() {
return page;
}
}