2 * Copyright (C) 2007 David Watson <dwatson@mimvista.com>
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
18 package org
.spearce
.egit
.ui
.internal
.dialogs
;
21 import java
.io
.IOException
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Collections
;
24 import java
.util
.Iterator
;
26 import org
.eclipse
.core
.resources
.IFile
;
27 import org
.eclipse
.jface
.dialogs
.Dialog
;
28 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
29 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
30 import org
.eclipse
.jface
.layout
.GridDataFactory
;
31 import org
.eclipse
.jface
.viewers
.CheckboxTableViewer
;
32 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
33 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
34 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
35 import org
.eclipse
.jface
.viewers
.Viewer
;
36 import org
.eclipse
.swt
.SWT
;
37 import org
.eclipse
.swt
.events
.SelectionEvent
;
38 import org
.eclipse
.swt
.events
.SelectionListener
;
39 import org
.eclipse
.swt
.graphics
.Image
;
40 import org
.eclipse
.swt
.layout
.GridLayout
;
41 import org
.eclipse
.swt
.widgets
.Button
;
42 import org
.eclipse
.swt
.widgets
.Composite
;
43 import org
.eclipse
.swt
.widgets
.Control
;
44 import org
.eclipse
.swt
.widgets
.Event
;
45 import org
.eclipse
.swt
.widgets
.Label
;
46 import org
.eclipse
.swt
.widgets
.Listener
;
47 import org
.eclipse
.swt
.widgets
.Menu
;
48 import org
.eclipse
.swt
.widgets
.MenuItem
;
49 import org
.eclipse
.swt
.widgets
.Shell
;
50 import org
.eclipse
.swt
.widgets
.Table
;
51 import org
.eclipse
.swt
.widgets
.TableColumn
;
52 import org
.eclipse
.swt
.widgets
.Text
;
53 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
54 import org
.spearce
.egit
.core
.project
.GitProjectData
;
55 import org
.spearce
.egit
.core
.project
.RepositoryMapping
;
56 import org
.spearce
.jgit
.lib
.GitIndex
;
57 import org
.spearce
.jgit
.lib
.PersonIdent
;
58 import org
.spearce
.jgit
.lib
.Repository
;
59 import org
.spearce
.jgit
.lib
.Tree
;
60 import org
.spearce
.jgit
.lib
.TreeEntry
;
61 import org
.spearce
.jgit
.lib
.GitIndex
.Entry
;
64 * @author dwatson Dialog is shown to user when they request to commit files.
65 * Changes in the selected portion of the tree are shown.
67 public class CommitDialog
extends Dialog
{
69 class CommitLabelProvider
extends WorkbenchLabelProvider
implements
71 public String
getColumnText(Object obj
, int columnIndex
) {
72 IFile file
= (IFile
) obj
;
74 return file
.getProject().getName() + ": "
75 + file
.getProjectRelativePath();
77 else if (columnIndex
== 0) {
78 String prefix
= "Unknown";
80 final GitProjectData projectData
= GitProjectData
.get(file
83 RepositoryMapping repositoryMapping
= projectData
84 .getRepositoryMapping(file
.getProject());
86 Repository repo
= repositoryMapping
.getRepository();
87 GitIndex index
= repo
.getIndex();
88 Tree headTree
= repo
.mapTree("HEAD");
90 String repoPath
= repositoryMapping
91 .getRepoRelativePath(file
);
92 TreeEntry headEntry
= headTree
.findBlobMember(repoPath
);
93 boolean headExists
= headTree
.existsBlob(repoPath
);
95 Entry indexEntry
= index
.getEntry(repoPath
);
96 if (headEntry
== null) {
98 if (indexEntry
.isModified(repositoryMapping
.getWorkDir()))
99 prefix
= "Added, index diff";
100 } else if (indexEntry
== null) {
102 } else if (headExists
103 && !headEntry
.getId().equals(
104 indexEntry
.getObjectId())) {
108 if (indexEntry
.isModified(repositoryMapping
.getWorkDir()))
109 prefix
= "Mod., index diff";
110 } else if (!new File(repositoryMapping
.getWorkDir(), indexEntry
.getName()).isFile()) {
111 prefix
= "Rem., not staged";
112 } else if (indexEntry
.isModified(repositoryMapping
.getWorkDir())) {
113 prefix
= "Mod., not staged";
116 } catch (Exception e
) {
124 public Image
getColumnImage(Object element
, int columnIndex
) {
125 if (columnIndex
== 0)
126 return getImage(element
);
131 ArrayList
<IFile
> files
;
136 public CommitDialog(Shell parentShell
) {
141 protected void createButtonsForButtonBar(Composite parent
) {
142 createButton(parent
, IDialogConstants
.SELECT_ALL_ID
, "Select All", false);
143 createButton(parent
, IDialogConstants
.DESELECT_ALL_ID
, "Deselect All", false);
145 createButton(parent
, IDialogConstants
.OK_ID
, "Commit", true);
146 createButton(parent
, IDialogConstants
.CANCEL_ID
,
147 IDialogConstants
.CANCEL_LABEL
, true);
152 Button amendingButton
;
153 Button signedOffButton
;
155 CheckboxTableViewer filesViewer
;
158 protected Control
createDialogArea(Composite parent
) {
159 Composite container
= (Composite
) super.createDialogArea(parent
);
160 parent
.getShell().setText("Commit Changes");
162 GridLayout layout
= new GridLayout(2, false);
163 container
.setLayout(layout
);
165 Label label
= new Label(container
, SWT
.LEFT
);
166 label
.setText("Commit Message:");
167 label
.setLayoutData(GridDataFactory
.fillDefaults().span(2, 1).create());
169 commitText
= new Text(container
, SWT
.MULTI
| SWT
.BORDER
| SWT
.V_SCROLL
);
170 commitText
.setLayoutData(GridDataFactory
.fillDefaults().span(2, 1)
171 .hint(600, 200).create());
173 new Label(container
, SWT
.LEFT
).setText("Author: ");
174 authorText
= new Text(container
, SWT
.BORDER
);
175 authorText
.setLayoutData(GridDataFactory
.fillDefaults().grab(true, false).create());
177 authorText
.setText(author
);
179 amendingButton
= new Button(container
, SWT
.CHECK
);
181 amendingButton
.setSelection(amending
);
182 amendingButton
.setEnabled(false); // if already set, don't allow any changes
183 commitText
.setText(previousCommitMessage
);
185 amendingButton
.addSelectionListener(new SelectionListener() {
186 boolean alreadyAdded
= false;
187 public void widgetSelected(SelectionEvent arg0
) {
190 if (amendingButton
.getSelection()) {
192 String curText
= commitText
.getText();
193 if (curText
.length() > 0)
195 commitText
.setText(curText
+ previousCommitMessage
);
199 public void widgetDefaultSelected(SelectionEvent arg0
) {
203 amendingButton
.setText("Amend previous commit");
204 amendingButton
.setLayoutData(GridDataFactory
.fillDefaults().grab(true, false).span(2, 1).create());
206 signedOffButton
= new Button(container
, SWT
.CHECK
);
207 signedOffButton
.setSelection(signedOff
);
208 signedOffButton
.setText("Add Signed-off-by");
209 signedOffButton
.setLayoutData(GridDataFactory
.fillDefaults().grab(true, false).span(2, 1).create());
211 Table resourcesTable
= new Table(container
, SWT
.H_SCROLL
| SWT
.V_SCROLL
212 | SWT
.FULL_SELECTION
| SWT
.MULTI
| SWT
.CHECK
| SWT
.BORDER
);
213 resourcesTable
.setLayoutData(GridDataFactory
.fillDefaults().hint(600,
214 200).span(2,1).create());
216 resourcesTable
.setHeaderVisible(true);
217 TableColumn statCol
= new TableColumn(resourcesTable
, SWT
.LEFT
);
218 statCol
.setText("Status");
219 statCol
.setWidth(150);
221 TableColumn resourceCol
= new TableColumn(resourcesTable
, SWT
.LEFT
);
222 resourceCol
.setText("File");
223 resourceCol
.setWidth(415);
225 filesViewer
= new CheckboxTableViewer(resourcesTable
);
226 filesViewer
.setContentProvider(new IStructuredContentProvider() {
228 public void inputChanged(Viewer viewer
, Object oldInput
,
232 public void dispose() {
235 public Object
[] getElements(Object inputElement
) {
236 return files
.toArray();
240 filesViewer
.setLabelProvider(new CommitLabelProvider());
241 filesViewer
.setInput(files
);
242 filesViewer
.setAllChecked(true);
243 filesViewer
.getTable().setMenu(getContextMenu());
249 private Menu
getContextMenu() {
250 Menu menu
= new Menu(filesViewer
.getTable());
251 MenuItem item
= new MenuItem(menu
, SWT
.PUSH
);
252 item
.setText("Add file on disk to index");
253 item
.addListener(SWT
.Selection
, new Listener() {
254 public void handleEvent(Event arg0
) {
255 IStructuredSelection sel
= (IStructuredSelection
) filesViewer
.getSelection();
259 for (Iterator
<Object
> it
= sel
.iterator(); it
.hasNext();) {
260 IFile file
= (IFile
) it
.next();
262 final GitProjectData projectData
= GitProjectData
.get(file
264 RepositoryMapping repositoryMapping
= projectData
265 .getRepositoryMapping(file
.getProject());
267 Repository repo
= repositoryMapping
.getRepository();
268 GitIndex index
= null;
270 index
= repo
.getIndex();
271 Entry entry
= index
.getEntry(repositoryMapping
.getRepoRelativePath(file
));
272 if (entry
!= null && entry
.isModified(repositoryMapping
.getWorkDir())) {
273 entry
.update(new File(repositoryMapping
.getWorkDir(), entry
.getName()), repo
);
275 } catch (IOException e
) {
280 filesViewer
.refresh(true);
287 public String
getCommitMessage() {
288 return commitMessage
;
291 public void setCommitMessage(String s
) {
292 this.commitMessage
= s
;
295 private String commitMessage
= "";
296 private String author
= null;
297 private boolean signedOff
= false;
298 private boolean amending
= false;
300 private ArrayList
<IFile
> selectedItems
= new ArrayList
<IFile
>();
301 private String previousCommitMessage
= "";
303 public void setSelectedItems(IFile
[] items
) {
304 Collections
.addAll(selectedItems
, items
);
307 public IFile
[] getSelectedItems() {
308 return selectedItems
.toArray(new IFile
[0]);
312 protected void okPressed() {
313 commitMessage
= commitText
.getText();
314 author
= authorText
.getText().trim();
315 signedOff
= signedOffButton
.getSelection();
316 amending
= amendingButton
.getSelection();
318 Object
[] checkedElements
= filesViewer
.getCheckedElements();
319 selectedItems
.clear();
320 for (Object obj
: checkedElements
)
321 selectedItems
.add((IFile
) obj
);
323 if (commitMessage
.trim().length() == 0) {
324 MessageDialog
.openWarning(getShell(), "No message", "You must enter a commit message");
328 if (author
.length() > 0) {
330 new PersonIdent(author
);
331 } catch (IllegalArgumentException e
) {
332 MessageDialog
.openWarning(getShell(), "Invalid author", "Invalid author specified. Please use the form:\nA U Thor <author@example.com>");
335 } else author
= null;
337 if (selectedItems
.isEmpty() && !amending
) {
338 MessageDialog
.openWarning(getShell(), "No items selected", "No items are currently selected to be committed.");
344 public void setFileList(ArrayList
<IFile
> files
) {
349 protected void buttonPressed(int buttonId
) {
350 if (IDialogConstants
.SELECT_ALL_ID
== buttonId
) {
351 filesViewer
.setAllChecked(true);
353 if (IDialogConstants
.DESELECT_ALL_ID
== buttonId
) {
354 filesViewer
.setAllChecked(false);
356 super.buttonPressed(buttonId
);
359 public String
getAuthor() {
363 public void setAuthor(String author
) {
364 this.author
= author
;
367 public boolean isSignedOff() {
371 public void setSignedOff(boolean signedOff
) {
372 this.signedOff
= signedOff
;
375 public boolean isAmending() {
379 public void setAmending(boolean amending
) {
380 this.amending
= amending
;
383 public void setPreviousCommitMessage(String string
) {
384 this.previousCommitMessage
= string
;