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
;
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
;
84 private IFileRevision
[] fileRevisions
;
86 public GitHistoryPage(Object object
) {
90 public boolean inputSet() {
92 viewer
.setInput(getInput());
93 // TODO Auto-generated method stub
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(
115 final GitCompareRevisionAction compareActionPrev
= new GitCompareRevisionAction(
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(
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);
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
}));
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);
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
) {
187 public String
getColumnText(Object element
, int columnIndex
) {
188 if (columnIndex
== 0) {
189 int count
= ((GitFileRevision
) element
).getCount();
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
));
206 return patch
.getName();
209 if (id
.length() > 9) // make sure "Workspace" is spelled out
210 return id
.substring(0, 7) + "..";
214 return id
+ "@.." + rs
;
217 if (columnIndex
== 2)
220 if (columnIndex
== 3)
221 return new Date(((IFileRevision
) element
).getTimestamp())
224 if (columnIndex
== 4)
225 return ((IFileRevision
) element
).getAuthor();
227 if (columnIndex
== 5) {
228 String comment
= ((IFileRevision
) element
).getComment();
231 int p
= comment
.indexOf('\n');
233 return comment
.substring(0, p
);
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
) {
253 TreeItem item
= (TreeItem
) event
.item
;
254 Tree parent
= item
.getParent();
255 if (parent
== null) {
256 item
.setText(new String
[] { "hej", "san" });
259 ITableLabelProvider p
= (ITableLabelProvider
) viewer
261 for (int i
= 0; i
< 6; ++i
) {
262 String text
= p
.getColumnText(
263 fileRevisions
[event
.index
], i
);
265 item
.setText(i
, text
);
269 item
.setData(fileRevisions
[event
.index
]);
271 } catch (Throwable b
) {
276 TableLayout layout
= new TableLayout();
277 tree
.setLayout(layout
);
279 viewer
= new TreeViewer(tree
, SWT
.VIRTUAL
| SWT
.FULL_SELECTION
);
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)
298 System
.out
.println("inputChanged(" + viewer
+ "," + oldInput
+ ","
300 IProject project
= ((IResource
) getInput()).getProject();
301 RepositoryProvider provider
= RepositoryProvider
302 .getProvider(project
);
303 RepositoryMapping repositoryMapping
= ((GitProvider
)provider
).getData().getRepositoryMapping(project
);
305 appliedPatches
= null;
306 appliedPatches
= repositoryMapping
.getRepository().getAppliedPatches();
307 } catch (IOException e
) {
308 // TODO Auto-generated catch block
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();
318 tree
.setItemCount(fileRevisions
.length
);
319 tree
.setData(fileRevisions
);
320 System
.out
.println("inputchanged, invoking 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
340 public Object
getParent(Object element
) {
341 // System.out.println("getParent(" + element + ")");
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);
362 TreeColumn col
= new TreeColumn(tree
, SWT
.NONE
);
363 col
.setResizable(true);
365 // X col.addSelectionListener(headerListener);
366 ((TableLayout
) tree
.getLayout()).addColumnData(new ColumnWeightData(10,
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,
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,
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,
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,
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,
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
430 public void refresh() {
431 // TODO Auto-generated method stub
435 public Object
getAdapter(Class adapter
) {
436 if (adapter
== IHistoryCompareAdapter
.class) {
442 public ICompareInput
getCompareInput(Object object
) {
443 // TODO Auto-generated method stub
447 public void prepareInput(ICompareInput input
,
448 CompareConfiguration configuration
, IProgressMonitor monitor
) {
449 System
.out
.println("prepareInput()");
450 // TODO Auto-generated method stub