diff options
16 files changed, 679 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF index 82ff0c5734..0b7da90b1e 100644 --- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF @@ -40,6 +40,7 @@ Import-Package: org.eclipse.egit.core;version="[1.0.0,1.1.0)", org.eclipse.egit.core.synchronize.dto;version="[1.0.0,1.1.0)", org.eclipse.jgit.api;version="[1.0.0,1.1.0)", org.eclipse.jgit.api.errors;version="[1.0.0,1.1.0)", + org.eclipse.jgit.blame;version="[1.0.0,1.1.0)", org.eclipse.jgit.diff;version="[1.0.0,1.1.0)", org.eclipse.jgit.dircache;version="[1.0.0,1.1.0)", org.eclipse.jgit.errors;version="[1.0.0,1.1.0)", diff --git a/org.eclipse.egit.ui/icons/etool16/annotate.gif b/org.eclipse.egit.ui/icons/etool16/annotate.gif Binary files differnew file mode 100644 index 0000000000..40afd5bfda --- /dev/null +++ b/org.eclipse.egit.ui/icons/etool16/annotate.gif diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties index 55c102e755..8487a0e11c 100644 --- a/org.eclipse.egit.ui/plugin.properties +++ b/org.eclipse.egit.ui/plugin.properties @@ -304,3 +304,4 @@ CommitSearchResults.label = Git Search Results NavigationActionSet.label = Git Navigation Actions OpenCommitAction.tooltip = Open Git Commit OpenCommitAction.label = Open Git Commit +ShowBlameAction_label = Show Blame Annotations diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml index 272fa9946d..0e64668fd7 100644 --- a/org.eclipse.egit.ui/plugin.xml +++ b/org.eclipse.egit.ui/plugin.xml @@ -218,6 +218,23 @@ label="%CompareWithRevisionAction_label" menubarPath="compareWithMenu/gitCompareWithGroup"/> </objectContribution> + <objectContribution + adaptable="true" + id="org.eclipse.egit.ui.gitFileContributions" + objectClass="org.eclipse.core.resources.IFile"> + <filter + name="projectPersistentProperty" + value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider"> + </filter> + <action + class="org.eclipse.egit.ui.internal.actions.ShowBlameAction" + enablesFor="1" + id="org.eclipse.egit.ui.internal.actions.ShowBlameAction" + label="%ShowBlameAction_label" + icon="icons/etool16/annotate.gif" + menubarPath="team.main/group10"> + </action> + </objectContribution> </extension> <extension diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIIcons.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIIcons.java index e132c07922..26e8d7d586 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIIcons.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIIcons.java @@ -185,6 +185,9 @@ public class UIIcons { /** Commit note icon */ public final static ImageDescriptor NOTE; + /** Show Annotation icon */ + public final static ImageDescriptor ANNOTATE; + /** base URL */ public final static URL base; @@ -251,6 +254,7 @@ public class UIIcons { AMEND_COMMIT = map("obj16/commit_amend.gif"); //$NON-NLS-1$ UNTRACKED_FILE = map("obj16/untracked_file.gif"); //$NON-NLS-1$ NOTE = map("obj16/note.png"); //$NON-NLS-1$ + ANNOTATE = map("etool16/annotate.gif"); //$NON-NLS-1$ } private static ImageDescriptor map(final String icon) { diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java index 7cb9815625..bca63087b5 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java @@ -97,6 +97,15 @@ public class UIText extends NLS { public static String AddToIndexCommand_addingFilesFailed; /** */ + public static String BlameInformationControl_Author; + + /** */ + public static String BlameInformationControl_Commit; + + /** */ + public static String BlameInformationControl_Committer; + + /** */ public static String AssumeUnchanged_assumeUnchanged; /** */ @@ -151,6 +160,9 @@ public class UIText extends NLS { public static String SharingWizard_MoveProjectActionLabel; /** */ + public static String ShowBlameHandler_JobName; + + /** */ public static String GenerateHistoryJob_BuildingListMessage; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java index 4de6fbbc15..6c2e21067f 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java @@ -129,6 +129,16 @@ public class UIUtils { } /** + * @param id + * see {@link FontRegistry#getItalic(String)} + * @return the font + */ + public static Font getItalicFont(final String id) { + return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme() + .getFontRegistry().getItalic(id); + } + + /** * Adds little bulb decoration to given control. Bulb will appear in top * left corner of control after giving focus for this control. * diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java index 60385ec901..fafcc136c1 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java @@ -125,4 +125,6 @@ public class ActionCommands { /** "Merge Tool" action command id */ public static final String MERGE_TOOL_ACTION = "org.eclipse.egit.ui.team.MergeTool"; //$NON-NLS-1$ + /** "Show Blame Annotations" action command id */ + public static final String SHOW_BLAME_ACTION = "org.eclipse.egit.ui.team.ShowBlameAnnotations"; //$NON-NLS-1$ } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameAction.java new file mode 100644 index 0000000000..973e23f2f8 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameAction.java @@ -0,0 +1,24 @@ +/****************************************************************************** + * 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.egit.ui.internal.actions; + +/** + * Show annotation action class. + */ +public class ShowBlameAction extends RepositoryAction { + + /** Create show annotation action */ + public ShowBlameAction() { + super(ActionCommands.SHOW_BLAME_ACTION, + new ShowBlameActionHandler()); + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java new file mode 100644 index 0000000000..3cc9d5115f --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java @@ -0,0 +1,40 @@ +/****************************************************************************** + * 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.egit.ui.internal.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.internal.blame.BlameOperation; +import org.eclipse.egit.ui.internal.job.JobUtil; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Show blame annotations action handler + */ +public class ShowBlameActionHandler extends RepositoryActionHandler { + + /** @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ + public Object execute(final ExecutionEvent event) throws ExecutionException { + IResource[] selected = getSelectedResources(); + Repository repository = getRepository(); + if (repository != null && selected.length == 1 + && selected[0] instanceof IFile) + JobUtil.scheduleUserJob(new BlameOperation(repository, + (IFile) selected[0], HandlerUtil.getActiveShell(event), + HandlerUtil.getActiveSite(event).getPage()), + UIText.ShowBlameHandler_JobName, null); + return null; + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/AuthorColors.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/AuthorColors.java new file mode 100644 index 0000000000..8c02a9942a --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/AuthorColors.java @@ -0,0 +1,78 @@ +/****************************************************************************** + * Copyright (c) 2005, 2008 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *****************************************************************************/ +package org.eclipse.egit.ui.internal.blame; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.graphics.RGB; + +/** + * Author colors + */ +public class AuthorColors { + + private static AuthorColors instance; + + private static final RGB[] COMMITTER_RGBs = new RGB[] { + new RGB(131, 150, 98), new RGB(221, 205, 93), + new RGB(199, 134, 57), new RGB(133, 166, 214), + new RGB(197, 123, 127), new RGB(139, 136, 140), + new RGB(48, 135, 144), new RGB(190, 93, 66), new RGB(143, 163, 54), + new RGB(180, 148, 74), new RGB(101, 101, 217), + new RGB(72, 153, 119), new RGB(23, 101, 160), + new RGB(132, 164, 118), new RGB(255, 230, 59), + new RGB(136, 176, 70), new RGB(255, 138, 1), new RGB(123, 187, 95), + new RGB(233, 88, 98), new RGB(93, 158, 254), new RGB(175, 215, 0), + new RGB(140, 134, 142), new RGB(232, 168, 21), + new RGB(0, 172, 191), new RGB(251, 58, 4), new RGB(63, 64, 255), + new RGB(27, 194, 130), new RGB(0, 104, 183) }; + + /** + * Returns the author color singleton. + * + * @return the author color singleton + */ + public static synchronized AuthorColors getDefault() { + if (instance == null) + instance = new AuthorColors(); + return instance; + } + + /** The color map. */ + private Map<String, RGB> colors; + + /** The number of colors that have been issued. */ + private int count; + + private AuthorColors() { + colors = new HashMap<String, RGB>(); + } + + /** + * Returns a unique color description for each string passed in. Colors for + * new authors are allocated to be as different as possible from the + * existing colors. + * + * @param author + * name + * @return the corresponding color + */ + public RGB getCommitterRGB(String author) { + RGB rgb = colors.get(author); + if (rgb == null) { + rgb = COMMITTER_RGBs[count++ % COMMITTER_RGBs.length]; + colors.put(author, rgb); + } + return rgb; + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java new file mode 100644 index 0000000000..4c772bb3d3 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java @@ -0,0 +1,195 @@ +/****************************************************************************** + * 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.egit.ui.internal.blame; + +import java.text.MessageFormat; + +import org.eclipse.egit.ui.Activator; +import org.eclipse.egit.ui.UIPreferences; +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.UIUtils; +import org.eclipse.egit.ui.internal.commit.CommitEditor; +import org.eclipse.egit.ui.internal.commit.RepositoryCommit; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceColors; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.AbstractInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StyledText; +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.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; + +/** + * Annotation information control + */ +public class BlameInformationControl extends AbstractInformationControl + implements IInformationControlExtension2 { + + private IInformationControlCreator creator; + + private BlameRevision revision; + + private ScrolledComposite scrolls; + + private Composite displayArea; + + private Hyperlink commitLink; + + private Label authorLabel; + + private Label committerLabel; + + private StyledText messageText; + + /** + * @param parentShell + * @param isResizable + * @param creator + */ + public BlameInformationControl(Shell parentShell, boolean isResizable, + IInformationControlCreator creator) { + super(parentShell, isResizable); + this.creator = creator; + create(); + } + + public IInformationControlCreator getInformationPresenterControlCreator() { + return this.creator; + } + + public boolean hasContents() { + return true; + } + + protected void createContent(Composite parent) { + scrolls = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL); + scrolls.setExpandHorizontal(true); + scrolls.setExpandVertical(true); + displayArea = new Composite(scrolls, SWT.NONE); + scrolls.setContent(displayArea); + displayArea.setForeground(parent.getForeground()); + displayArea.setBackground(parent.getBackground()); + displayArea.setBackgroundMode(SWT.INHERIT_FORCE); + GridLayoutFactory.swtDefaults().equalWidth(true).applyTo(displayArea); + + commitLink = new Hyperlink(displayArea, SWT.NONE); + commitLink.addHyperlinkListener(new HyperlinkAdapter() { + + public void linkActivated(HyperlinkEvent e) { + try { + getShell().dispose(); + CommitEditor.open(new RepositoryCommit(revision + .getRepository(), revision.getCommit())); + } catch (PartInitException pie) { + Activator.logError(pie.getLocalizedMessage(), pie); + } + } + + }); + commitLink.setUnderlined(true); + commitLink.setFont(JFaceResources.getBannerFont()); + commitLink.setForeground(JFaceColors.getHyperlinkText(commitLink + .getDisplay())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(commitLink); + + authorLabel = new Label(displayArea, SWT.NONE); + authorLabel.setForeground(parent.getForeground()); + authorLabel.setBackground(parent.getBackground()); + authorLabel.setFont(UIUtils.getItalicFont(JFaceResources.DEFAULT_FONT)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(authorLabel); + + committerLabel = new Label(displayArea, SWT.NONE); + committerLabel.setForeground(parent.getForeground()); + committerLabel.setBackground(parent.getBackground()); + committerLabel.setFont(UIUtils + .getItalicFont(JFaceResources.DEFAULT_FONT)); + GridDataFactory.fillDefaults().grab(true, false) + .applyTo(committerLabel); + + Label separator = new Label(displayArea, SWT.HORIZONTAL | SWT.SEPARATOR); + GridDataFactory.fillDefaults().grab(true, false).applyTo(separator); + + messageText = new StyledText(displayArea, SWT.NONE); + messageText.setForeground(parent.getForeground()); + messageText.setBackground(parent.getBackground()); + messageText.setEditable(false); + messageText.setFont(UIUtils + .getFont(UIPreferences.THEME_CommitMessageFont)); + GridDataFactory.fillDefaults().grab(true, true).applyTo(messageText); + } + + public Point computeSizeHint() { + Point computed = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + + Point constraints = getSizeConstraints(); + if (constraints == null) + return computed; + + Point constrainedSize = getShell().computeSize(constraints.x, + SWT.DEFAULT, true); + int width = Math.min(computed.x, constrainedSize.x); + int height = Math.max(computed.y, constrainedSize.y); + return new Point(width, height); + } + + private void setControlVisible(Control control, boolean visible) { + control.setVisible(visible); + ((GridData) control.getLayoutData()).exclude = !visible; + } + + public void setInput(Object input) { + this.revision = (BlameRevision) input; + + RevCommit commit = this.revision.getCommit(); + + commitLink.setText(MessageFormat.format( + UIText.BlameInformationControl_Commit, commit.name())); + + PersonIdent author = commit.getAuthorIdent(); + if (author != null) { + setControlVisible(authorLabel, true); + authorLabel.setText(MessageFormat.format( + UIText.BlameInformationControl_Author, + author.getName(), author.getEmailAddress(), + author.getWhen())); + } else + setControlVisible(authorLabel, false); + + PersonIdent committer = commit.getCommitterIdent(); + setControlVisible(authorLabel, author != null); + if (committer != null && !committer.equals(author)) { + setControlVisible(committerLabel, true); + committerLabel.setText(MessageFormat.format( + UIText.BlameInformationControl_Committer, + committer.getName(), committer.getEmailAddress(), + committer.getWhen())); + } else + setControlVisible(committerLabel, false); + + messageText.setText(commit.getFullMessage()); + + scrolls.setMinSize(displayArea.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControlCreator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControlCreator.java new file mode 100644 index 0000000000..59eb6b8ee9 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControlCreator.java @@ -0,0 +1,40 @@ +/****************************************************************************** + * 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.egit.ui.internal.blame; + +import org.eclipse.jface.text.AbstractReusableInformationControlCreator; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.swt.widgets.Shell; + +/** + * Annotation information control creator + */ +public class BlameInformationControlCreator extends + AbstractReusableInformationControlCreator { + + private boolean resizable; + + /** + * Create annotation information control creator + * + * @param resizable + */ + public BlameInformationControlCreator(boolean resizable) { + this.resizable = resizable; + } + + @Override + protected IInformationControl doCreateInformationControl(Shell parent) { + return new BlameInformationControl(parent, resizable, + new BlameInformationControlCreator(true)); + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java new file mode 100644 index 0000000000..9235aab019 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java @@ -0,0 +1,125 @@ +/****************************************************************************** + * 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.egit.ui.internal.blame; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.egit.core.op.IEGitOperation; +import org.eclipse.egit.core.project.RepositoryMapping; +import org.eclipse.egit.ui.Activator; +import org.eclipse.jface.text.revisions.RevisionInformation; +import org.eclipse.jgit.api.BlameCommand; +import org.eclipse.jgit.blame.BlameResult; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.ui.history.RevisionAnnotationController; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; + +/** + * Blame operation + */ +public class BlameOperation implements IEGitOperation { + + private Repository repository; + + private IFile file; + + private Shell shell; + + private IWorkbenchPage page; + + /** + * Create annotate operation + * + * @param repository + * @param file + * @param shell + * @param page + */ + public BlameOperation(Repository repository, IFile file, Shell shell, + IWorkbenchPage page) { + this.repository = repository; + this.file = file; + this.shell = shell; + this.page = page; + } + + public void execute(IProgressMonitor monitor) throws CoreException { + final RevisionInformation info = new RevisionInformation(); + info.setHoverControlCreator(new BlameInformationControlCreator(false)); + info.setInformationPresenterControlCreator(new BlameInformationControlCreator( + true)); + RepositoryMapping mapping = RepositoryMapping.getMapping(file + .getProject()); + if (mapping == null) + return; + BlameResult result = new BlameCommand(repository) + .setFollowFileRenames(true) + .setFilePath(mapping.getRepoRelativePath(file)).call(); + if (result == null) + return; + Map<RevCommit, BlameRevision> revisions = new HashMap<RevCommit, BlameRevision>(); + int lineCount = result.getResultContents().size(); + monitor.beginTask("", lineCount); //$NON-NLS-1$ + BlameRevision previous = null; + for (int i = 0; i < lineCount; i++) { + RevCommit commit = result.getSourceCommit(i); + BlameRevision revision = revisions.get(commit); + if (revision == null) { + revision = new BlameRevision(); + revision.setRepository(repository); + revision.setCommit(commit); + revisions.put(commit, revision); + info.addRevision(revision); + } + if (previous != null) + if (previous == revision) + previous.addLine(); + else { + previous.register(); + previous = revision.reset(i); + } + else + previous = revision.reset(i); + monitor.worked(1); + } + if (previous != null) + previous.register(); + + shell.getDisplay().asyncExec(new Runnable() { + public void run() { + try { + AbstractDecoratedTextEditor editor = RevisionAnnotationController + .openEditor(page, file); + if (editor != null) + editor.showRevisionInformation(info, + "org.eclipse.egit.ui.internal.decorators.GitQuickDiffProvider"); //$NON-NLS-1$ + } catch (PartInitException e) { + Activator.handleError( + "Error displaying blame annotations", e, //$NON-NLS-1$ + false); + } + } + }); + } + + public ISchedulingRule getSchedulingRule() { + return null; + } +}
\ No newline at end of file diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameRevision.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameRevision.java new file mode 100644 index 0000000000..910a59f990 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameRevision.java @@ -0,0 +1,126 @@ +/****************************************************************************** + * 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.egit.ui.internal.blame; + +import java.util.Date; + +import org.eclipse.jface.text.revisions.Revision; +import org.eclipse.jface.text.source.LineRange; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.swt.graphics.RGB; + +/** + * Annotation revision + */ +public class BlameRevision extends Revision { + + private int start; + + private int lines = 1; + + private RevCommit commit; + + private Repository repository; + + public Object getHoverInfo() { + return this; + } + + public RGB getColor() { + return AuthorColors.getDefault().getCommitterRGB(getAuthor()); + } + + public String getId() { + return commit.abbreviate(7).name(); + } + + public Date getDate() { + return commit.getAuthorIdent().getWhen(); + } + + /** + * Register revision + * + * @return this revision + */ + public BlameRevision register() { + addRange(new LineRange(start, lines)); + return this; + } + + /** + * Increment line count + * + * @return this revision + */ + public BlameRevision addLine() { + lines++; + return this; + } + + /** + * Reset revision + * + * @param number + * @return this revision + */ + public BlameRevision reset(int number) { + start = number; + lines = 1; + return this; + } + + /** + * Set revision + * + * @param commit + * @return this + */ + public BlameRevision setCommit(RevCommit commit) { + this.commit = commit; + return this; + } + + /** + * Get revision + * + * @return revision + */ + public RevCommit getCommit() { + return this.commit; + } + + /** + * Set repository + * + * @param repository + * @return this + */ + public BlameRevision setRepository(Repository repository) { + this.repository = repository; + return this; + } + + /** + * Get repository + * + * @return repository + */ + public Repository getRepository() { + return this.repository; + } + + public String getAuthor() { + return commit.getAuthorIdent().getName(); + } + +}
\ No newline at end of file diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties index 403e2ea851..7c6f5db887 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties @@ -31,6 +31,9 @@ AddConfigEntryDialog_MustEnterKeyMessage=Please enter a key AddConfigEntryDialog_ValueLabel=&Value AddToIndexAction_addingFiles=Adding files to Git Index AddToIndexCommand_addingFilesFailed=Adding files failed +BlameInformationControl_Author=Author: {0} <{1}> {2} +BlameInformationControl_Commit=Commit {0} +BlameInformationControl_Committer=Committer: {0} <{1}> {2} AssumeUnchanged_assumeUnchanged=Assume Unchanged AssumeUnchanged_noAssumeUnchanged=No Assume Unchanged WizardProjectsImportPage_ImportProjectsTitle=Import Projects @@ -51,6 +54,7 @@ SelectResetTypePage_PageTitle=Reset {0} SharingWizard_windowTitle=Configure Git Repository SharingWizard_failed=Failed to initialize Git team provider. SharingWizard_MoveProjectActionLabel=Move project +ShowBlameHandler_JobName=Computing blame annotations GenerateHistoryJob_BuildingListMessage=Building commit list for "{0}" ... GenerateHistoryJob_CancelMessage=Reading commit list was canceled for "{0}" |