blob: 3e6a94d296a5d11a7d444948e1e88fd1e4737355 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2012 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.builds.ui.editor;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.mylyn.builds.core.IBuild;
import org.eclipse.mylyn.builds.core.IChange;
import org.eclipse.mylyn.builds.core.IChangeArtifact;
import org.eclipse.mylyn.builds.core.IChangeSet;
import org.eclipse.mylyn.builds.internal.core.Change;
import org.eclipse.mylyn.builds.internal.core.ChangeArtifact;
import org.eclipse.mylyn.internal.builds.ui.BuildsUiPlugin;
import org.eclipse.mylyn.internal.team.ui.actions.TaskFinder;
import org.eclipse.mylyn.versions.core.ScmArtifact;
import org.eclipse.mylyn.versions.core.ScmCore;
import org.eclipse.mylyn.versions.core.spi.ScmConnector;
import org.eclipse.mylyn.versions.ui.ScmUi;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.statushandlers.StatusManager;
/**
* @author Steffen Pingel
*/
public class ChangesPart extends AbstractBuildEditorPart {
static class ChangesContentProvider implements ITreeContentProvider {
private static final Object[] NO_ELEMENTS = new Object[0];
private IChangeSet input;
public void dispose() {
input = null;
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (newInput instanceof IChangeSet) {
input = (IChangeSet) newInput;
} else {
input = null;
}
}
public Object[] getElements(Object inputElement) {
if (inputElement == input) {
return input.getChanges().toArray();
} else if (inputElement instanceof String) {
return new Object[] { inputElement };
}
return NO_ELEMENTS;
}
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof IChange) {
return ((IChange) parentElement).getArtifacts().toArray();
}
return NO_ELEMENTS;
}
public Object getParent(Object element) {
if (element instanceof EObject) {
return ((EObject) element).eContainer();
}
return null;
}
public boolean hasChildren(Object element) {
if (element instanceof IChangeSet) {
return !((IChangeSet) element).getChanges().isEmpty();
}
if (element instanceof IChange) {
return !((IChange) element).getArtifacts().isEmpty();
}
return false;
}
}
private TreeViewer viewer;
private MenuManager menuManager;
private static final String ID_POPUP_MENU = "org.eclipse.mylyn.builds.ui.editor.menu.Changes"; //$NON-NLS-1$
public ChangesPart() {
super(ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
setPartName("Changes");
setExpandVertically(true);
this.span = 2;
}
@Override
protected Control createContent(Composite parent, FormToolkit toolkit) {
Composite composite = toolkit.createComposite(parent);
composite.setLayout(new GridLayout(1, false));
IChangeSet changeSet = getInput(IBuild.class).getChangeSet();
// if (changeSet == null || changeSet.getChanges().isEmpty()) {
// createLabel(composite, toolkit, "No changes.");
// }
viewer = new TreeViewer(toolkit.createTree(composite, SWT.H_SCROLL));
GridDataFactory.fillDefaults().hint(500, 100).grab(true, true).applyTo(viewer.getControl());
viewer.setContentProvider(new ChangesContentProvider());
viewer.setLabelProvider(new DecoratingStyledCellLabelProvider(new ChangesLabelProvider(), null, null));
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
getPage().getSite().getSelectionProvider().setSelection(event.getSelection());
}
});
viewer.addOpenListener(new IOpenListener() {
public void open(OpenEvent event) {
Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
if (selection instanceof Change) {
ChangesPart.this.open((Change) selection);
}
if (selection instanceof ChangeArtifact) {
try {
ChangesPart.this.open((ChangeArtifact) selection);
} catch (CoreException e) {
e.printStackTrace();
}
}
}
});
menuManager = new MenuManager();
menuManager.setRemoveAllWhenShown(true);
getPage().getEditorSite().registerContextMenu(ID_POPUP_MENU, menuManager, viewer, true);
Menu menu = menuManager.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
if (changeSet == null || changeSet.getChanges().isEmpty()) {
viewer.setInput("No changes.");
} else {
viewer.setInput(changeSet);
}
toolkit.paintBordersFor(composite);
return composite;
}
private void open(IChangeArtifact changeArtifact) throws CoreException {
final IResource resource = ScmCore.findResource(changeArtifact.getFile());
if (resource == null) {
getMessageManager().addMessage(ChangesPart.class.getName(),
"The selected file is not available in the workspace", null, IMessageProvider.WARNING);
return;
}
final ScmConnector connector = ScmCore.getConnector(resource);
if (connector == null) {
getMessageManager().addMessage(ChangesPart.class.getName(),
"No extension available to open the selected file", null, IMessageProvider.WARNING);
return;
}
final String prevRevision = changeArtifact.getPrevRevision();
final String revision = (changeArtifact.getRevision() != null)
? changeArtifact.getRevision()
: ((IChange) ((ChangeArtifact) changeArtifact).eContainer()).getRevision();
if (revision == null) {
getMessageManager().addMessage(ChangesPart.class.getName(),
"Could not determine change revisions for the selected file", null, IMessageProvider.WARNING);
}
try {
final AtomicReference<IFileRevision> left = new AtomicReference<IFileRevision>();
final AtomicReference<IFileRevision> right = new AtomicReference<IFileRevision>();
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
ScmArtifact rightArtifact = connector.getArtifact(resource, revision);
right.set(rightArtifact.getFileRevision(monitor));
if (prevRevision != null) {
ScmArtifact leftArtifact = connector.getArtifact(resource, prevRevision);
left.set(leftArtifact.getFileRevision(monitor));
}
if (left.get() == null) {
try {
IFileRevision[] contributors = rightArtifact.getContributors(monitor);
if (contributors != null && contributors.length > 0) {
left.set(contributors[0]);
}
} catch (UnsupportedOperationException e) {
// ignore
}
}
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
}
});
if (right.get() != null) {
getMessageManager().removeMessage(ChangesPart.class.getName());
ScmUi.openCompareEditor(getPage().getSite().getPage(), left.get(), right.get());
} else {
getMessageManager().addMessage(ChangesPart.class.getName(),
"Could not determine change revisions for the selected file", null, IMessageProvider.WARNING);
}
} catch (InvocationTargetException e) {
StatusManager.getManager().handle(
new Status(IStatus.ERROR, BuildsUiPlugin.ID_PLUGIN, "Unexpected error", e),
StatusManager.SHOW | StatusManager.LOG);
} catch (InterruptedException e) {
// ignore
}
}
private void open(IChange selection) {
TaskReference reference = new TaskReference();
reference.setText(selection.getMessage());
TaskFinder finder = new TaskFinder(reference);
finder.open();
}
}