Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Sawicki2011-05-30 20:12:44 +0000
committerChris Aniszczyk2011-05-31 19:13:34 +0000
commit42a957063a1f7366abb80d68cebcd225e87ea43c (patch)
treeb04c15ad953251e620218d55fa00507674fa37de
parent38298ff0f85401604648d94cda9f1804e37789dc (diff)
downloadegit-42a957063a1f7366abb80d68cebcd225e87ea43c.tar.gz
egit-42a957063a1f7366abb80d68cebcd225e87ea43c.tar.xz
egit-42a957063a1f7366abb80d68cebcd225e87ea43c.zip
Add handler to display blame annotations in editor ruler.
Bug: 306161 Change-Id: I3d66bdd19800f4c9a1da720673c267685041fba1 Signed-off-by: Kevin Sawicki <kevin@github.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
-rw-r--r--org.eclipse.egit.ui/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.egit.ui/icons/etool16/annotate.gifbin0 -> 592 bytes
-rw-r--r--org.eclipse.egit.ui/plugin.properties1
-rw-r--r--org.eclipse.egit.ui/plugin.xml17
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIIcons.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java12
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java10
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java2
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameAction.java24
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java40
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/AuthorColors.java78
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java195
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControlCreator.java40
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java125
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameRevision.java126
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties4
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 82ff0c573..0b7da90b1 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
new file mode 100644
index 000000000..40afd5bfd
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/etool16/annotate.gif
Binary files differ
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index 55c102e75..8487a0e11 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 272fa9946..0e64668fd 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 e132c0792..26e8d7d58 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 7cb981562..bca63087b 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 4de6fbbc1..6c2e21067 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 60385ec90..fafcc136c 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 000000000..973e23f2f
--- /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 000000000..3cc9d5115
--- /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 000000000..8c02a9942
--- /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 000000000..4c772bb3d
--- /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 000000000..59eb6b8ee
--- /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 000000000..9235aab01
--- /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 000000000..910a59f99
--- /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 403e2ea85..7c6f5db88 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}"

Back to the top