1 /*******************************************************************************
2 * Copyright (c) 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 * Robin Rosenberg - Git interface
11 *******************************************************************************/
12 package org
.spearce
.egit
.ui
.internal
.actions
;
14 import org
.eclipse
.compare
.CompareEditorInput
;
15 import org
.eclipse
.compare
.CompareUI
;
16 import org
.eclipse
.compare
.ITypedElement
;
17 import org
.eclipse
.core
.resources
.IResource
;
18 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
19 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
20 import org
.eclipse
.osgi
.util
.NLS
;
21 import org
.eclipse
.team
.core
.history
.IFileRevision
;
22 import org
.eclipse
.team
.core
.history
.provider
.FileRevision
;
23 import org
.eclipse
.team
.internal
.core
.history
.LocalFileRevision
;
24 import org
.eclipse
.team
.internal
.ui
.TeamUIMessages
;
25 import org
.eclipse
.team
.internal
.ui
.history
.AbstractHistoryCategory
;
26 import org
.eclipse
.team
.internal
.ui
.synchronize
.LocalResourceTypedElement
;
27 import org
.eclipse
.team
.ui
.history
.HistoryPage
;
28 import org
.eclipse
.ui
.IEditorInput
;
29 import org
.eclipse
.ui
.IEditorPart
;
30 import org
.eclipse
.ui
.IEditorReference
;
31 import org
.eclipse
.ui
.IReusableEditor
;
32 import org
.eclipse
.ui
.IWorkbenchPage
;
33 import org
.eclipse
.ui
.actions
.BaseSelectionListenerAction
;
34 import org
.spearce
.egit
.core
.GitWorkspaceFileRevision
;
35 import org
.spearce
.egit
.core
.internal
.mapping
.GitFileRevision
;
36 import org
.spearce
.egit
.ui
.internal
.GitCompareFileRevisionEditorInput
;
37 import org
.spearce
.egit
.ui
.internal
.GitResourceNode
;
38 import org
.spearce
.jgit
.lib
.ObjectId
;
41 * Action to invoke a Git based compare on selected revivsions in the history window.
43 * This class i almost a verbatim copy of @{link org.eclipse.team.internal.ui.actions.CompareRevisionAction}
44 * since it could not be subclassed to invoke the EGit methods.
46 public class GitCompareRevisionAction
extends BaseSelectionListenerAction
{
49 IStructuredSelection selection
;
50 IFileRevision currentFileRevision
;
52 public GitCompareRevisionAction(String text
) {
56 public GitCompareRevisionAction() {
57 this(TeamUIMessages
.LocalHistoryPage_CompareAction
);
61 IStructuredSelection structSel
= selection
;
62 Object
[] objArray
= structSel
.toArray();
64 IFileRevision file1
= null;
65 IFileRevision file2
= null;
67 switch (structSel
.size()){
69 file1
= getCurrentFileRevision();
70 Object tempRevision
= objArray
[0];
71 if (tempRevision
instanceof IFileRevision
)
72 file2
= (IFileRevision
) tempRevision
;
78 Object tempRevision2
= objArray
[0];
79 Object tempRevision3
= objArray
[1];
81 if (tempRevision2
instanceof IFileRevision
&&
82 tempRevision3
instanceof IFileRevision
){
83 file1
= (IFileRevision
) objArray
[0];
84 file2
= (IFileRevision
) objArray
[1];
90 if (file1
== null || file2
== null ||
91 !file1
.exists() || !file2
.exists()){
92 MessageDialog
.openError(page
.getSite().getShell(),
93 TeamUIMessages
.OpenRevisionAction_DeletedRevTitle
,
94 TeamUIMessages
.CompareRevisionAction_DeleteCompareMessage
);
98 IResource resource
= getResource(file2
);
99 if (resource
!= null) {
100 IFileRevision temp
= file1
;
105 resource
= getResource(file1
);
106 if (resource
!= null) {
107 right
= new LocalResourceTypedElement(resource
);
109 right
= new GitResourceNode(file1
);
111 ITypedElement left
= new GitResourceNode(file2
);
113 openInCompare(left
, right
);
116 private void openInCompare(ITypedElement left
, ITypedElement right
) {
117 CompareEditorInput input
= createCompareEditorInput(left
, right
, page
.getSite().getPage());
118 IWorkbenchPage workBenchPage
= page
.getSite().getPage();
119 IEditorPart editor
= findReusableCompareEditor(workBenchPage
);
120 if (editor
!= null) {
121 IEditorInput otherInput
= editor
.getEditorInput();
122 if (otherInput
.equals(input
)) {
123 // simply provide focus to editor
124 workBenchPage
.activate(editor
);
126 // if editor is currently not open on that input either re-use
128 CompareUI
.reuseCompareEditor(input
, (IReusableEditor
) editor
);
129 workBenchPage
.activate(editor
);
132 CompareUI
.openCompareEditor(input
);
136 protected GitCompareFileRevisionEditorInput
createCompareEditorInput(
137 ITypedElement left
, ITypedElement right
, IWorkbenchPage page
) {
138 return new GitCompareFileRevisionEditorInput(left
, right
, page
);
141 private IResource
getResource(IFileRevision revision
) {
142 if (revision
instanceof GitWorkspaceFileRevision
) {
143 GitWorkspaceFileRevision local
= (GitWorkspaceFileRevision
) revision
;
144 return local
.getResource();
149 private IFileRevision
getCurrentFileRevision() {
150 return currentFileRevision
;
153 public void setCurrentFileRevision(IFileRevision fileRevision
){
154 this.currentFileRevision
= fileRevision
;
158 * Returns an editor that can be re-used. An open compare editor that
159 * has un-saved changes cannot be re-used.
161 * @return an EditorPart or <code>null</code> if none can be found
163 public static IEditorPart
findReusableCompareEditor(IWorkbenchPage page
) {
164 IEditorReference
[] editorRefs
= page
.getEditorReferences();
165 for (int i
= 0; i
< editorRefs
.length
; i
++) {
166 IEditorPart part
= editorRefs
[i
].getEditor(false);
168 && (part
.getEditorInput() instanceof GitCompareFileRevisionEditorInput
)
169 && part
instanceof IReusableEditor
) {
170 if(! part
.isDirty()) {
178 protected boolean updateSelection(IStructuredSelection selection
) {
179 this.selection
= selection
;
180 if (selection
.size() == 1){
181 Object el
= selection
.getFirstElement();
182 if (el
instanceof LocalFileRevision
)
183 this.setText(TeamUIMessages
.CompareRevisionAction_Local
);
184 else if (el
instanceof FileRevision
){
185 FileRevision tempFileRevision
= (FileRevision
) el
;
186 this.setText(NLS
.bind(TeamUIMessages
.CompareRevisionAction_Revision
, new String
[]{tempFileRevision
.getContentIdentifier()}));
189 this.setText(TeamUIMessages
.CompareRevisionAction_CompareWithCurrent
);
192 else if (selection
.size() == 2){
193 IFileRevision rev1
=(IFileRevision
)selection
.toArray()[0];
194 IFileRevision rev2
=(IFileRevision
)selection
.toArray()[1];
195 System
.out
.println("Compare "+rev1
.getContentIdentifier()+" with "+rev2
.getContentIdentifier());
196 if (rev1
instanceof GitFileRevision
&& rev2
instanceof GitFileRevision
) {
197 ObjectId pid
= ((GitFileRevision
)rev1
).getCommit().getParentIds()[0];
198 if (pid
.equals(((GitFileRevision
)rev2
).getCommit().getCommitId())) {
199 this.setText("Show commit diff");
201 this.setText(TeamUIMessages
.CompareRevisionAction_CompareWithOther
);
204 this.setText(TeamUIMessages
.CompareRevisionAction_CompareWithOther
);
211 public void setPage(HistoryPage page
) {
215 private boolean shouldShow() {
216 IStructuredSelection structSel
= selection
;
217 Object
[] objArray
= structSel
.toArray();
219 if (objArray
.length
== 0)
222 // Comparing the workspace revision with itself is just stupid
223 if (objArray
.length
== 1 && objArray
[0] instanceof GitWorkspaceFileRevision
)
226 for (int i
= 0; i
< objArray
.length
; i
++) {
228 // Don't bother showing if this a category
229 if (objArray
[i
] instanceof AbstractHistoryCategory
)
232 IFileRevision revision
= (IFileRevision
) objArray
[i
];
233 //check to see if any of the selected revisions are deleted revisions
234 if (revision
!= null && !revision
.exists())