/****************************************************************************** * Copyright (c) 2011 GitHub Inc. * 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: * Kevin Sawicki (GitHub Inc.) - initial API and implementation *****************************************************************************/ package org.eclipse.mylyn.internal.github.ui.pr; import java.io.IOException; import java.text.MessageFormat; import org.eclipse.core.commands.common.CommandException; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.egit.github.core.PullRequest; import org.eclipse.egit.ui.UIUtils; import org.eclipse.egit.ui.internal.UIIcons; import org.eclipse.egit.ui.internal.commit.CommitEditor; import org.eclipse.egit.ui.internal.commit.RepositoryCommit; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider; import org.eclipse.jface.viewers.IOpenListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.mylyn.internal.github.core.GitHub; import org.eclipse.mylyn.internal.github.core.issue.IssueConnector; import org.eclipse.mylyn.internal.github.core.pr.PullRequestComposite; import org.eclipse.mylyn.internal.github.core.pr.PullRequestUtils; import org.eclipse.mylyn.internal.github.ui.GitHubUi; import org.eclipse.mylyn.internal.github.ui.TaskDataHandler; import org.eclipse.mylyn.internal.tasks.ui.editors.AbstractTaskEditorSection; import org.eclipse.mylyn.tasks.ui.TasksUiUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; /** * Task editor section to view commits attached to a pull request */ public class CommitAttributePart extends AbstractTaskEditorSection { private CommandContributionItem fetchCommits; private CommandContributionItem checkoutPr; private CommandContributionItem mergePr; private CommandContributionItem rebasePr; private PullRequestComposite request; /** * Create commit attribute part * * @param request */ public CommitAttributePart(PullRequestComposite request) { setPartName(Messages.CommitAttributePart_PartName); this.request = request; } protected Control createContent(FormToolkit toolkit, Composite parent) { Composite displayArea = toolkit.createComposite(parent); GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(displayArea); GridDataFactory.fillDefaults().grab(true, true).applyTo(displayArea); if (request != null) { Composite refArea = toolkit.createComposite(displayArea); GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(4) .applyTo(refArea); GridDataFactory.swtDefaults().grab(true, false).applyTo(refArea); Image branchIcon = UIIcons.BRANCH.createImage(); UIUtils.hookDisposal(refArea, branchIcon); CLabel sourceLabel = new CLabel(refArea, SWT.NONE); toolkit.adapt(sourceLabel, false, false); sourceLabel.setText(Messages.CommitAttributePart_LabelSource); sourceLabel.setImage(branchIcon); sourceLabel.setForeground(toolkit.getColors().getColor( IFormColors.TITLE)); toolkit.createText(refArea, request.getRequest().getHead() .getLabel(), SWT.READ_ONLY); CLabel destLabel = new CLabel(refArea, SWT.NONE); toolkit.adapt(destLabel, false, false); destLabel.setText(Messages.CommitAttributePart_LabelDestination); destLabel.setImage(branchIcon); destLabel.setForeground(toolkit.getColors().getColor( IFormColors.TITLE)); GridDataFactory.swtDefaults().indent(15, 0).applyTo(destLabel); toolkit.createText(refArea, request.getRequest().getBase() .getLabel(), SWT.READ_ONLY); } Composite treeArea = toolkit.createComposite(displayArea); toolkit.paintBordersFor(treeArea); GridLayoutFactory.fillDefaults().spacing(0, 0) .extendedMargins(2, 2, 2, 7).applyTo(treeArea); GridDataFactory.fillDefaults().grab(true, true).applyTo(treeArea); TreeViewer commitViewer = new TreeViewer(toolkit.createTree(treeArea, SWT.V_SCROLL | SWT.H_SCROLL | toolkit.getBorderStyle())); commitViewer.setContentProvider(new WorkbenchContentProvider()); commitViewer.setLabelProvider(new DelegatingStyledCellLabelProvider( new WorkbenchLabelProvider())); GridDataFactory.fillDefaults().grab(true, true) .applyTo(commitViewer.getControl()); commitViewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); commitViewer.addOpenListener(new IOpenListener() { public void open(final OpenEvent event) { PullRequest pr = request.getRequest(); Repository repo = PullRequestUtils.getRepository(pr); if (repo != null) openCommits(repo, ((IStructuredSelection) event .getSelection()).toArray()); else PullRequestConnectorUi.showNoRepositoryDialog(pr); } }); int size = 0; if (request != null) { PullRequestAdapter root = new PullRequestAdapter(request); size = root.getChildren(root).length; commitViewer.setInput(root); Point treeSize = commitViewer.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT); ((GridData) commitViewer.getControl().getLayoutData()).heightHint = Math .min(treeSize.y, 200); } getSection().setText( MessageFormat.format( Messages.CommitAttributePart_SectionCommits, size)); return displayArea; } private void openCommits(final Repository repository, final Object[] elements) { if (elements.length == 0) return; if (repository == null) return; try (RevWalk walk = new RevWalk(repository)) { for (Object element : elements) { String id = ((PullRequestCommitAdapter) element).getCommit() .getSha(); try { CommitEditor.openQuiet(new RepositoryCommit(repository, walk.parseCommit(ObjectId.fromString(id)))); } catch (MissingObjectException ignored) { boolean fetch = MessageDialog.openQuestion(getControl() .getShell(), Messages.CommitAttributePart_TitleFetch, Messages.CommitAttributePart_MessageFetch); if (fetch) { fetchCommits(new Runnable() { public void run() { PlatformUI.getWorkbench().getDisplay() .asyncExec(new Runnable() { public void run() { openCommits(repository, elements); } }); } }); } } } } catch (IOException e) { GitHubUi.logError(e); } } private CommandContributionItem createCommandContributionItem( String commandId) { CommandContributionItemParameter parameter = new CommandContributionItemParameter( getTaskEditorPage().getEditorSite(), commandId, commandId, CommandContributionItem.STYLE_PUSH); return new CommandContributionItem(parameter); } protected void fillToolBar(ToolBarManager toolBarManager) { if (TasksUiUtil.isOutgoingNewTask(getTaskEditorPage().getTask(), IssueConnector.KIND)) return; if (request == null) return; checkoutPr = createCommandContributionItem(CheckoutPullRequestHandler.ID); fetchCommits = createCommandContributionItem(FetchPullRequestHandler.ID); mergePr = createCommandContributionItem(MergePullRequestHandler.ID); rebasePr = createCommandContributionItem(RebasePullRequestHandler.ID); // Disable actions for now // toolBarManager.add(checkoutPr); toolBarManager.add(fetchCommits); // toolBarManager.add(mergePr); // toolBarManager.add(rebasePr); } @Override protected String getInfoOverlayText() { return request != null ? request.getRequest().getHead().getLabel() : null; } protected boolean shouldExpandOnCreate() { return true; } private void fetchCommits(final Runnable postHandler) { IHandlerService handlerService = (IHandlerService) getTaskEditorPage() .getEditorSite().getService(IHandlerService.class); try { IEvaluationContext context = TaskDataHandler.createContext( new StructuredSelection(getTaskData()), handlerService); if (postHandler != null) context.addVariable(TaskDataHandler.POST_HANDLER_CALLBACK, postHandler); handlerService.executeCommandInContext(fetchCommits.getCommand(), new Event(), context); } catch (CommandException e) { GitHub.logError(e); } } }