Show patch name in history view
[egit.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / GitHistoryPage.java
blobc72e1f18be40a9cc116fd60a3c5e0a35f0a98189
1 /*
2 * Copyright (C) 2006 Robin Rosenberg
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License, version 2.1, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org.spearce.egit.ui;
19 import java.io.IOException;
20 import java.util.Date;
21 import java.util.Map;
23 import org.eclipse.compare.CompareConfiguration;
24 import org.eclipse.compare.structuremergeviewer.ICompareInput;
25 import org.eclipse.core.resources.IProject;
26 import org.eclipse.core.resources.IResource;
27 import org.eclipse.core.resources.IResourceChangeEvent;
28 import org.eclipse.core.resources.IResourceChangeListener;
29 import org.eclipse.core.resources.ResourcesPlugin;
30 import org.eclipse.core.runtime.IAdaptable;
31 import org.eclipse.core.runtime.IProgressMonitor;
32 import org.eclipse.jface.action.IMenuListener;
33 import org.eclipse.jface.action.IMenuManager;
34 import org.eclipse.jface.action.MenuManager;
35 import org.eclipse.jface.viewers.ColumnWeightData;
36 import org.eclipse.jface.viewers.ILazyTreeContentProvider;
37 import org.eclipse.jface.viewers.ITableLabelProvider;
38 import org.eclipse.jface.viewers.ITreeContentProvider;
39 import org.eclipse.jface.viewers.LabelProvider;
40 import org.eclipse.jface.viewers.StructuredSelection;
41 import org.eclipse.jface.viewers.TableLayout;
42 import org.eclipse.jface.viewers.TreeViewer;
43 import org.eclipse.jface.viewers.Viewer;
44 import org.eclipse.swt.SWT;
45 import org.eclipse.swt.events.SelectionAdapter;
46 import org.eclipse.swt.events.SelectionEvent;
47 import org.eclipse.swt.graphics.Image;
48 import org.eclipse.swt.layout.GridData;
49 import org.eclipse.swt.layout.GridLayout;
50 import org.eclipse.swt.widgets.Composite;
51 import org.eclipse.swt.widgets.Control;
52 import org.eclipse.swt.widgets.Event;
53 import org.eclipse.swt.widgets.Listener;
54 import org.eclipse.swt.widgets.Menu;
55 import org.eclipse.swt.widgets.Tree;
56 import org.eclipse.swt.widgets.TreeColumn;
57 import org.eclipse.swt.widgets.TreeItem;
58 import org.eclipse.team.core.RepositoryProvider;
59 import org.eclipse.team.core.history.IFileHistory;
60 import org.eclipse.team.core.history.IFileHistoryProvider;
61 import org.eclipse.team.core.history.IFileRevision;
62 import org.eclipse.team.internal.ui.TeamUIMessages;
63 import org.eclipse.team.internal.ui.history.DialogHistoryPageSite;
64 import org.eclipse.team.ui.history.HistoryPage;
65 import org.eclipse.team.ui.history.IHistoryCompareAdapter;
66 import org.eclipse.team.ui.history.IHistoryPageSite;
67 import org.spearce.egit.core.GitProvider;
68 import org.spearce.egit.core.internal.mapping.GitFileRevision;
69 import org.spearce.egit.core.project.RepositoryMapping;
70 import org.spearce.egit.ui.internal.actions.GitCompareRevisionAction;
71 import org.spearce.jgit.lib.Commit;
72 import org.spearce.jgit.lib.ObjectId;
73 import org.spearce.jgit.lib.Repository.StGitPatch;
75 public class GitHistoryPage extends HistoryPage implements IAdaptable,
76 IHistoryCompareAdapter {
78 private Composite localComposite;
80 private TreeViewer viewer;
82 private Tree tree;
84 private IFileRevision[] fileRevisions;
86 public GitHistoryPage(Object object) {
87 setInput(object);
90 public boolean inputSet() {
91 if (viewer != null)
92 viewer.setInput(getInput());
93 // TODO Auto-generated method stub
94 return true;
97 public void createControl(Composite parent) {
98 localComposite = new Composite(parent, SWT.NONE);
99 GridLayout layout = new GridLayout();
100 layout.marginHeight = 0;
101 layout.marginWidth = 0;
102 localComposite.setLayout(layout);
103 GridData data = new GridData(GridData.FILL_BOTH);
104 data.grabExcessVerticalSpace = true;
105 localComposite.setLayoutData(data);
107 createTree(localComposite);
109 IHistoryPageSite parentSite = getHistoryPageSite();
110 if (parentSite != null && parentSite instanceof DialogHistoryPageSite)
111 parentSite.setSelectionProvider(viewer);
113 final GitCompareRevisionAction compareAction = new GitCompareRevisionAction(
114 "Compare");
115 final GitCompareRevisionAction compareActionPrev = new GitCompareRevisionAction(
116 "Show commit");
117 tree.addSelectionListener(new SelectionAdapter() {
118 public void widgetSelected(SelectionEvent e) {
119 // update the current
120 TreeItem[] selection = tree.getSelection();
121 IFileRevision[] selection2 = new IFileRevision[selection.length];
122 for (int i = 0; i < selection.length; ++i) {
123 selection2[i] = (IFileRevision) selection[i].getData();
126 compareAction.setCurrentFileRevision(fileRevisions[0]);
127 compareAction.selectionChanged(new StructuredSelection(
128 selection2));
129 IProject project = ((IResource) getInput()).getProject();
130 GitProvider provider = (GitProvider)RepositoryProvider
131 .getProvider(project);
132 RepositoryMapping repositoryMapping = provider.getData().getRepositoryMapping(project);
133 ObjectId parentId = (ObjectId)((GitFileRevision)selection2[0]).getCommit().getParentIds().get(0);
134 try {
135 if (selection2.length == 1) {
136 Commit parent = repositoryMapping.getRepository().mapCommit(parentId);
137 IFileRevision previous = new GitFileRevision(parent,
138 ((GitFileRevision)selection2[0]).getResource(),
139 ((GitFileRevision)selection2[0]).getCount()+1);
140 // compareActionPrev.setCurrentFileRevision(selection2[0]);
141 compareActionPrev.setCurrentFileRevision(null);
142 compareActionPrev.selectionChanged(new StructuredSelection(new IFileRevision[] {selection2[0], previous}));
143 } else {
144 compareActionPrev.setCurrentFileRevision(null);
145 compareActionPrev.selectionChanged(new StructuredSelection(new IFileRevision[0]));
147 } catch (IOException e1) {
148 // TODO Auto-generated catch block
149 e1.printStackTrace();
153 compareAction.setPage(this);
154 compareActionPrev.setPage(this);
155 MenuManager menuMgr = new MenuManager();
156 Menu menu = menuMgr.createContextMenu(tree);
157 menuMgr.addMenuListener(new IMenuListener() {
158 public void menuAboutToShow(IMenuManager menuMgr) {
159 menuMgr.add(compareAction);
160 menuMgr.add(compareActionPrev);
163 menuMgr.setRemoveAllWhenShown(true);
164 tree.setMenu(menu);
166 GitHistoryResourceListener resourceListener = new GitHistoryResourceListener();
167 ResourcesPlugin.getWorkspace().addResourceChangeListener(
168 resourceListener, IResourceChangeEvent.POST_CHANGE);
172 class GitHistoryResourceListener implements IResourceChangeListener {
174 public void resourceChanged(IResourceChangeEvent event) {
175 System.out.println("resourceChanged(" + event + ")");
180 class GitHistoryLabelProvider extends LabelProvider implements
181 ITableLabelProvider {
183 public Image getColumnImage(Object element, int columnIndex) {
184 return null;
187 public String getColumnText(Object element, int columnIndex) {
188 if (columnIndex == 0) {
189 int count = ((GitFileRevision) element).getCount();
190 if (count < 0)
191 return "";
192 else
193 if (count == 0)
194 return "HEAD";
195 else
196 return "HEAD~"+count;
199 if (columnIndex == 1) {
200 String rss = ((IFileRevision) element).getURI().toString();
201 String rs = rss.substring(rss.length()-10);
202 String id = ((IFileRevision) element).getContentIdentifier();
203 if (appliedPatches!=null) {
204 StGitPatch patch = (StGitPatch) appliedPatches.get(new ObjectId(id));
205 if (patch!=null)
206 return patch.getName();
208 if (id != null)
209 if (id.length() > 9) // make sure "Workspace" is spelled out
210 return id.substring(0, 7) + "..";
211 else
212 return id;
213 else
214 return id + "@.." + rs;
217 if (columnIndex == 2)
218 return ""; // TAGS
220 if (columnIndex == 3)
221 return new Date(((IFileRevision) element).getTimestamp())
222 .toString();
224 if (columnIndex == 4)
225 return ((IFileRevision) element).getAuthor();
227 if (columnIndex == 5) {
228 String comment = ((IFileRevision) element).getComment();
229 if (comment == null)
230 return null;
231 int p = comment.indexOf('\n');
232 if (p >= 0)
233 return comment.substring(0, p);
234 else
235 return comment;
237 return Integer.toString(columnIndex);
241 private void createTree(Composite composite) {
242 tree = new Tree(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
243 | SWT.FULL_SELECTION | SWT.VIRTUAL);
244 tree.setHeaderVisible(true);
245 tree.setLinesVisible(true);
247 GridData data = new GridData(GridData.FILL_BOTH);
248 tree.setLayoutData(data);
249 tree.setData("HEAD");
250 tree.addListener(SWT.SetData, new Listener() {
251 public void handleEvent(Event event) {
252 try {
253 TreeItem item = (TreeItem) event.item;
254 Tree parent = item.getParent();
255 if (parent == null) {
256 item.setText(new String[] { "hej", "san" });
257 item.setData("");
258 } else {
259 ITableLabelProvider p = (ITableLabelProvider) viewer
260 .getLabelProvider();
261 for (int i = 0; i < 6; ++i) {
262 String text = p.getColumnText(
263 fileRevisions[event.index], i);
264 if (text != null)
265 item.setText(i, text);
266 else
267 item.setText(i, "");
269 item.setData(fileRevisions[event.index]);
271 } catch (Throwable b) {
272 b.printStackTrace();
276 TableLayout layout = new TableLayout();
277 tree.setLayout(layout);
279 viewer = new TreeViewer(tree, SWT.VIRTUAL | SWT.FULL_SELECTION);
281 createColumns();
283 viewer.setLabelProvider(new GitHistoryLabelProvider());
285 viewer.setContentProvider(new GitHistoryContentProvider());
287 viewer.setInput(getInput());
290 private Map appliedPatches;
292 class GitHistoryContentProvider implements ITreeContentProvider,
293 ILazyTreeContentProvider {
295 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
296 if (newInput == null)
297 return;
298 System.out.println("inputChanged(" + viewer + "," + oldInput + ","
299 + newInput);
300 IProject project = ((IResource) getInput()).getProject();
301 RepositoryProvider provider = RepositoryProvider
302 .getProvider(project);
303 RepositoryMapping repositoryMapping = ((GitProvider)provider).getData().getRepositoryMapping(project);
304 try {
305 appliedPatches = null;
306 appliedPatches = repositoryMapping.getRepository().getAppliedPatches();
307 } catch (IOException e) {
308 // TODO Auto-generated catch block
309 e.printStackTrace();
311 IFileHistoryProvider fileHistoryProvider = provider
312 .getFileHistoryProvider();
313 IFileHistory fileHistoryFor = fileHistoryProvider
314 .getFileHistoryFor((IResource) getInput(),
315 IFileHistoryProvider.SINGLE_LINE_OF_DESCENT, null/* monitor */);
316 fileRevisions = fileHistoryFor.getFileRevisions();
317 tree.clearAll(true);
318 tree.setItemCount(fileRevisions.length);
319 tree.setData(fileRevisions);
320 System.out.println("inputchanged, invoking refresh");
321 viewer.refresh();
322 tree.getParent().layout();
323 tree.getParent().getParent().layout();
326 public void dispose() {
327 // TODO Auto-generated method stub
330 public Object[] getElements(Object inputElement) {
331 System.out.println("getElements(" + inputElement + ")");
332 return fileRevisions;
335 public boolean hasChildren(Object element) {
336 // TODO Auto-generated method stub
337 return false;
340 public Object getParent(Object element) {
341 // System.out.println("getParent(" + element + ")");
342 return null;
345 public Object[] getChildren(Object parentElement) {
346 // System.out.println("getElements(" + parentElement + ")");
347 return fileRevisions;
350 public void updateChildCount(Object element, int currentChildCount) {
351 viewer.setChildCount(element, fileRevisions.length);
354 public void updateElement(Object parent, int index) {
355 viewer.replace(parent, index, fileRevisions[index]);
359 private void createColumns() {
360 // X SelectionListener headerListener = getColumnListener(viewer);
361 // count from head
362 TreeColumn col = new TreeColumn(tree, SWT.NONE);
363 col.setResizable(true);
364 col.setText("^");
365 // X col.addSelectionListener(headerListener);
366 ((TableLayout) tree.getLayout()).addColumnData(new ColumnWeightData(10,
367 true));
369 // revision
370 col = new TreeColumn(tree, SWT.NONE);
371 col.setResizable(true);
372 col.setText(TeamUIMessages.GenericHistoryTableProvider_Revision);
373 // X col.addSelectionListener(headerListener);
374 ((TableLayout) tree.getLayout()).addColumnData(new ColumnWeightData(10,
375 true));
377 // tags
378 col = new TreeColumn(tree, SWT.NONE);
379 col.setResizable(true);
380 // X col.setText(CVSUIMessages.HistoryView_tags);
381 // X col.addSelectionListener(headerListener);
382 ((TableLayout) tree.getLayout()).addColumnData(new ColumnWeightData(20,
383 true));
384 // creation date
385 col = new TreeColumn(tree, SWT.NONE);
386 col.setResizable(true);
387 col.setText(TeamUIMessages.GenericHistoryTableProvider_RevisionTime);
388 // X col.addSelectionListener(headerListener);
389 ((TableLayout) tree.getLayout()).addColumnData(new ColumnWeightData(20,
390 true));
392 // author
393 col = new TreeColumn(tree, SWT.NONE);
394 col.setResizable(true);
395 col.setText(TeamUIMessages.GenericHistoryTableProvider_Author);
396 // X col.addSelectionListener(headerListener);
397 ((TableLayout) tree.getLayout()).addColumnData(new ColumnWeightData(20,
398 true));
400 // comment
401 col = new TreeColumn(tree, SWT.NONE);
402 col.setResizable(true);
403 col.setText(TeamUIMessages.GenericHistoryTableProvider_Comment);
404 // X col.addSelectionListener(headerListener);
405 ((TableLayout) tree.getLayout()).addColumnData(new ColumnWeightData(50,
406 true));
409 public Control getControl() {
410 return localComposite;
413 public void setFocus() {
414 localComposite.setFocus();
417 public String getDescription() {
418 return "GIT History viewer";
421 public String getName() {
422 return getInput().toString();
425 public boolean isValidInput(Object object) {
426 // TODO Auto-generated method stub
427 return true;
430 public void refresh() {
431 // TODO Auto-generated method stub
435 public Object getAdapter(Class adapter) {
436 if (adapter == IHistoryCompareAdapter.class) {
437 return this;
439 return null;
442 public ICompareInput getCompareInput(Object object) {
443 // TODO Auto-generated method stub
444 return null;
447 public void prepareInput(ICompareInput input,
448 CompareConfiguration configuration, IProgressMonitor monitor) {
449 System.out.println("prepareInput()");
450 // TODO Auto-generated method stub