Remove System.out.println from RevWalkFilterTest
[jgit.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / internal / dialogs / CommitDialog.java
blobce7196fa1e9a09ee8412a4e13cf2ced5931533c6
1 /*******************************************************************************
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com.dewire.com>
4 * Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com>
5 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
6 * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
8 * All rights reserved. This program and the accompanying materials
9 * are made available under the terms of the Eclipse Public License v1.0
10 * See LICENSE for the full license text, also available.
11 *******************************************************************************/
12 package org.spearce.egit.ui.internal.dialogs;
14 import java.io.File;
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.Comparator;
19 import java.util.Iterator;
21 import org.eclipse.compare.CompareUI;
22 import org.eclipse.compare.ITypedElement;
23 import org.eclipse.core.resources.IFile;
24 import org.eclipse.core.resources.IProject;
25 import org.eclipse.jface.dialogs.Dialog;
26 import org.eclipse.jface.dialogs.IDialogConstants;
27 import org.eclipse.jface.dialogs.MessageDialog;
28 import org.eclipse.jface.layout.GridDataFactory;
29 import org.eclipse.jface.viewers.CheckboxTableViewer;
30 import org.eclipse.jface.viewers.IStructuredContentProvider;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.viewers.ITableLabelProvider;
33 import org.eclipse.jface.viewers.Viewer;
34 import org.eclipse.jface.viewers.ViewerComparator;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.events.KeyAdapter;
37 import org.eclipse.swt.events.KeyEvent;
38 import org.eclipse.swt.events.ModifyEvent;
39 import org.eclipse.swt.events.ModifyListener;
40 import org.eclipse.swt.events.SelectionAdapter;
41 import org.eclipse.swt.events.SelectionEvent;
42 import org.eclipse.swt.events.SelectionListener;
43 import org.eclipse.swt.graphics.Image;
44 import org.eclipse.swt.layout.GridLayout;
45 import org.eclipse.swt.widgets.Button;
46 import org.eclipse.swt.widgets.Composite;
47 import org.eclipse.swt.widgets.Control;
48 import org.eclipse.swt.widgets.Event;
49 import org.eclipse.swt.widgets.Label;
50 import org.eclipse.swt.widgets.Listener;
51 import org.eclipse.swt.widgets.Menu;
52 import org.eclipse.swt.widgets.MenuItem;
53 import org.eclipse.swt.widgets.Shell;
54 import org.eclipse.swt.widgets.Table;
55 import org.eclipse.swt.widgets.TableColumn;
56 import org.eclipse.swt.widgets.Text;
57 import org.eclipse.team.core.RepositoryProvider;
58 import org.eclipse.team.core.history.IFileHistory;
59 import org.eclipse.team.core.history.IFileRevision;
60 import org.eclipse.team.internal.ui.history.FileRevisionTypedElement;
61 import org.eclipse.ui.model.WorkbenchLabelProvider;
62 import org.spearce.egit.core.Activator;
63 import org.spearce.egit.core.GitProvider;
64 import org.spearce.egit.core.internal.storage.GitFileHistoryProvider;
65 import org.spearce.egit.core.project.RepositoryMapping;
66 import org.spearce.egit.ui.UIText;
67 import org.spearce.egit.ui.internal.GitCompareFileRevisionEditorInput;
68 import org.spearce.jgit.lib.Commit;
69 import org.spearce.jgit.lib.Constants;
70 import org.spearce.jgit.lib.GitIndex;
71 import org.spearce.jgit.lib.PersonIdent;
72 import org.spearce.jgit.lib.Repository;
73 import org.spearce.jgit.lib.Tree;
74 import org.spearce.jgit.lib.TreeEntry;
75 import org.spearce.jgit.lib.GitIndex.Entry;
77 /**
78 * Dialog is shown to user when they request to commit files. Changes in the
79 * selected portion of the tree are shown.
81 public class CommitDialog extends Dialog {
83 class CommitContentProvider implements IStructuredContentProvider {
85 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
86 // Empty
89 public void dispose() {
90 // Empty
93 public Object[] getElements(Object inputElement) {
94 return items.toArray();
99 class CommitLabelProvider extends WorkbenchLabelProvider implements
100 ITableLabelProvider {
101 public String getColumnText(Object obj, int columnIndex) {
102 CommitItem item = (CommitItem) obj;
104 switch (columnIndex) {
105 case 0:
106 return item.status;
108 case 1:
109 return item.file.getProject().getName() + ": " //$NON-NLS-1$
110 + item.file.getProjectRelativePath();
112 default:
113 return null;
117 public Image getColumnImage(Object element, int columnIndex) {
118 if (columnIndex == 0)
119 return getImage(element);
120 return null;
124 ArrayList<CommitItem> items = new ArrayList<CommitItem>();
127 * @param parentShell
129 public CommitDialog(Shell parentShell) {
130 super(parentShell);
133 @Override
134 protected void createButtonsForButtonBar(Composite parent) {
135 createButton(parent, IDialogConstants.SELECT_ALL_ID, UIText.CommitDialog_SelectAll, false);
136 createButton(parent, IDialogConstants.DESELECT_ALL_ID, UIText.CommitDialog_DeselectAll, false);
138 createButton(parent, IDialogConstants.OK_ID, UIText.CommitDialog_Commit, true);
139 createButton(parent, IDialogConstants.CANCEL_ID,
140 IDialogConstants.CANCEL_LABEL, false);
143 Text commitText;
144 Text authorText;
145 Text committerText;
146 Button amendingButton;
147 Button signedOffButton;
149 CheckboxTableViewer filesViewer;
151 @Override
152 protected Control createDialogArea(Composite parent) {
153 Composite container = (Composite) super.createDialogArea(parent);
154 parent.getShell().setText(UIText.CommitDialog_CommitChanges);
156 GridLayout layout = new GridLayout(2, false);
157 container.setLayout(layout);
159 Label label = new Label(container, SWT.LEFT);
160 label.setText(UIText.CommitDialog_CommitMessage);
161 label.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, false).create());
163 commitText = new Text(container, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
164 commitText.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, true)
165 .hint(600, 200).create());
167 // allow to commit with ctrl-enter
168 commitText.addKeyListener(new KeyAdapter() {
169 public void keyPressed(KeyEvent arg0) {
170 if (arg0.keyCode == SWT.CR
171 && (arg0.stateMask & SWT.CONTROL) > 0) {
172 okPressed();
173 } else if (arg0.keyCode == SWT.TAB
174 && (arg0.stateMask & SWT.SHIFT) == 0) {
175 arg0.doit = false;
176 commitText.traverse(SWT.TRAVERSE_TAB_NEXT);
181 new Label(container, SWT.LEFT).setText(UIText.CommitDialog_Author);
182 authorText = new Text(container, SWT.BORDER);
183 authorText.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
184 if (author != null)
185 authorText.setText(author);
187 new Label(container, SWT.LEFT).setText(UIText.CommitDialog_Committer);
188 committerText = new Text(container, SWT.BORDER);
189 committerText.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
190 if (committer != null)
191 committerText.setText(committer);
192 committerText.addModifyListener(new ModifyListener() {
193 String oldCommitter = committerText.getText();
194 public void modifyText(ModifyEvent e) {
195 if (signedOffButton.getSelection()) {
196 // the commit message is signed
197 // the signature must be updated
198 String newCommitter = committerText.getText();
199 String oldSignOff = getSignedOff(oldCommitter);
200 String newSignOff = getSignedOff(newCommitter);
201 commitText.setText(replaceSignOff(commitText.getText(), oldSignOff, newSignOff));
202 oldCommitter = newCommitter;
207 amendingButton = new Button(container, SWT.CHECK);
208 if (amending) {
209 amendingButton.setSelection(amending);
210 amendingButton.setEnabled(false); // if already set, don't allow any changes
211 commitText.setText(previousCommitMessage);
212 authorText.setText(previousAuthor);
213 } else if (!amendAllowed) {
214 amendingButton.setEnabled(false);
216 amendingButton.addSelectionListener(new SelectionListener() {
217 boolean alreadyAdded = false;
218 public void widgetSelected(SelectionEvent arg0) {
219 if (alreadyAdded)
220 return;
221 if (amendingButton.getSelection()) {
222 alreadyAdded = true;
223 String curText = commitText.getText();
224 if (curText.length() > 0)
225 curText += "\n"; //$NON-NLS-1$
226 commitText.setText(curText + previousCommitMessage);
227 authorText.setText(previousAuthor);
231 public void widgetDefaultSelected(SelectionEvent arg0) {
232 // Empty
236 amendingButton.setText(UIText.CommitDialog_AmendPreviousCommit);
237 amendingButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, 1).create());
239 signedOffButton = new Button(container, SWT.CHECK);
240 signedOffButton.setSelection(signedOff);
241 signedOffButton.setText(UIText.CommitDialog_AddSOB);
242 signedOffButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, 1).create());
244 signedOffButton.addSelectionListener(new SelectionListener() {
245 public void widgetSelected(SelectionEvent arg0) {
246 String curText = commitText.getText();
247 if (signedOffButton.getSelection()) {
248 // add signed off line
249 commitText.setText(signOff(curText));
250 } else {
251 // remove signed off line
252 curText = replaceSignOff(curText, getSignedOff(), "");
253 if (curText.endsWith(Text.DELIMITER + Text.DELIMITER))
254 curText = curText.substring(0, curText.length() - Text.DELIMITER.length());
255 commitText.setText(curText);
259 public void widgetDefaultSelected(SelectionEvent arg0) {
260 // Empty
264 commitText.addModifyListener(new ModifyListener() {
265 public void modifyText(ModifyEvent e) {
266 updateSignedOffButton();
269 updateSignedOffButton();
271 Table resourcesTable = new Table(container, SWT.H_SCROLL | SWT.V_SCROLL
272 | SWT.FULL_SELECTION | SWT.MULTI | SWT.CHECK | SWT.BORDER);
273 resourcesTable.setLayoutData(GridDataFactory.fillDefaults().hint(600,
274 200).span(2,1).grab(true, true).create());
276 resourcesTable.addSelectionListener(new CommitItemSelectionListener());
278 resourcesTable.setHeaderVisible(true);
279 TableColumn statCol = new TableColumn(resourcesTable, SWT.LEFT);
280 statCol.setText(UIText.CommitDialog_Status);
281 statCol.setWidth(150);
282 statCol.addSelectionListener(new HeaderSelectionListener(CommitItem.Order.ByStatus));
284 TableColumn resourceCol = new TableColumn(resourcesTable, SWT.LEFT);
285 resourceCol.setText(UIText.CommitDialog_File);
286 resourceCol.setWidth(415);
287 resourceCol.addSelectionListener(new HeaderSelectionListener(CommitItem.Order.ByFile));
289 filesViewer = new CheckboxTableViewer(resourcesTable);
290 filesViewer.setContentProvider(new CommitContentProvider());
291 filesViewer.setLabelProvider(new CommitLabelProvider());
292 filesViewer.setInput(items);
293 filesViewer.setAllChecked(true);
294 filesViewer.getTable().setMenu(getContextMenu());
296 container.pack();
297 return container;
300 private void updateSignedOffButton() {
301 String curText = commitText.getText();
302 if (!curText.endsWith(Text.DELIMITER))
303 curText += Text.DELIMITER;
305 signedOffButton.setSelection(curText.indexOf(getSignedOff() + Text.DELIMITER) != -1);
308 private String getSignedOff() {
309 return getSignedOff(committerText.getText());
312 private String getSignedOff(String signer) {
313 return Constants.SIGNED_OFF_BY_TAG + signer;
316 private String signOff(String input) {
317 String output = input;
318 if (!output.endsWith(Text.DELIMITER))
319 output += Text.DELIMITER;
321 // if the last line is not a signed off (amend a commit), had a line break
322 if (!getLastLine(output).startsWith(Constants.SIGNED_OFF_BY_TAG))
323 output += Text.DELIMITER;
324 output += getSignedOff();
325 return output;
328 private String getLastLine(String input) {
329 String output = input;
330 int breakLength = Text.DELIMITER.length();
332 // remove last line break if exist
333 int lastIndexOfLineBreak = output.lastIndexOf(Text.DELIMITER);
334 if (lastIndexOfLineBreak != -1 && lastIndexOfLineBreak == output.length() - breakLength)
335 output = output.substring(0, output.length() - breakLength);
337 // get the last line
338 lastIndexOfLineBreak = output.lastIndexOf(Text.DELIMITER);
339 return lastIndexOfLineBreak == -1 ? output : output.substring(lastIndexOfLineBreak + breakLength, output.length());
342 private String replaceSignOff(String input, String oldSignOff, String newSignOff) {
343 assert input != null;
344 assert oldSignOff != null;
345 assert newSignOff != null;
347 String curText = input;
348 if (!curText.endsWith(Text.DELIMITER))
349 curText += Text.DELIMITER;
351 int indexOfSignOff = curText.indexOf(oldSignOff + Text.DELIMITER);
352 if (indexOfSignOff == -1)
353 return input;
355 return input.substring(0, indexOfSignOff) + newSignOff + input.substring(indexOfSignOff + oldSignOff.length(), input.length());
358 private Menu getContextMenu() {
359 Menu menu = new Menu(filesViewer.getTable());
360 MenuItem item = new MenuItem(menu, SWT.PUSH);
361 item.setText(UIText.CommitDialog_AddFileOnDiskToIndex);
362 item.addListener(SWT.Selection, new Listener() {
363 public void handleEvent(Event arg0) {
364 IStructuredSelection sel = (IStructuredSelection) filesViewer.getSelection();
365 if (sel.isEmpty()) {
366 return;
368 try {
369 ArrayList<GitIndex> changedIndexes = new ArrayList<GitIndex>();
370 for (Iterator<?> it = sel.iterator(); it.hasNext();) {
371 CommitItem commitItem = (CommitItem) it.next();
373 IProject project = commitItem.file.getProject();
374 RepositoryMapping map = RepositoryMapping.getMapping(project);
376 Repository repo = map.getRepository();
377 GitIndex index = null;
378 index = repo.getIndex();
379 Entry entry = index.getEntry(map.getRepoRelativePath(commitItem.file));
380 if (entry != null && entry.isModified(map.getWorkDir())) {
381 entry.update(new File(map.getWorkDir(), entry.getName()));
382 if (!changedIndexes.contains(index))
383 changedIndexes.add(index);
386 if (!changedIndexes.isEmpty()) {
387 for (GitIndex idx : changedIndexes) {
388 idx.write();
390 filesViewer.refresh(true);
392 } catch (IOException e) {
393 e.printStackTrace();
394 return;
399 return menu;
402 private static String getFileStatus(IFile file) {
403 String prefix = UIText.CommitDialog_StatusUnknown;
405 try {
406 RepositoryMapping repositoryMapping = RepositoryMapping
407 .getMapping(file.getProject());
409 Repository repo = repositoryMapping.getRepository();
410 GitIndex index = repo.getIndex();
411 Tree headTree = repo.mapTree(Constants.HEAD);
413 String repoPath = repositoryMapping.getRepoRelativePath(file);
414 TreeEntry headEntry = headTree.findBlobMember(repoPath);
415 boolean headExists = headTree.existsBlob(repoPath);
417 Entry indexEntry = index.getEntry(repoPath);
418 if (headEntry == null) {
419 prefix = UIText.CommitDialog_StatusAdded;
420 if (indexEntry.isModified(repositoryMapping.getWorkDir()))
421 prefix = UIText.CommitDialog_StatusAddedIndexDiff;
422 } else if (indexEntry == null) {
423 prefix = UIText.CommitDialog_StatusRemoved;
424 } else if (headExists
425 && !headEntry.getId().equals(indexEntry.getObjectId())) {
426 prefix = UIText.CommitDialog_StatusModified;
428 if (indexEntry.isModified(repositoryMapping.getWorkDir()))
429 prefix = UIText.CommitDialog_StatusModifiedIndexDiff;
430 } else if (!new File(repositoryMapping.getWorkDir(), indexEntry
431 .getName()).isFile()) {
432 prefix = UIText.CommitDialog_StatusRemovedNotStaged;
433 } else if (indexEntry.isModified(repositoryMapping.getWorkDir())) {
434 prefix = UIText.CommitDialog_StatusModifiedNotStaged;
437 } catch (Exception e) {
438 Activator.logError("Problem in finding file status", e);
439 prefix = e.getMessage();
442 return prefix;
446 * @return The message the user entered
448 public String getCommitMessage() {
449 return commitMessage.replaceAll(Text.DELIMITER, "\n"); //$NON-NLS-1$;
453 * Preset a commit message. This might be for amending a commit.
454 * @param s the commit message
456 public void setCommitMessage(String s) {
457 this.commitMessage = s;
460 private String commitMessage = ""; //$NON-NLS-1$
461 private String author = null;
462 private String committer = null;
463 private String previousAuthor = null;
464 private boolean signedOff = false;
465 private boolean amending = false;
466 private boolean amendAllowed = true;
468 private ArrayList<IFile> selectedFiles = new ArrayList<IFile>();
469 private String previousCommitMessage = ""; //$NON-NLS-1$
472 * Pre-select suggested set of resources to commit
474 * @param items
476 public void setSelectedFiles(IFile[] items) {
477 Collections.addAll(selectedFiles, items);
481 * @return the resources selected by the user to commit.
483 public IFile[] getSelectedFiles() {
484 return selectedFiles.toArray(new IFile[0]);
487 class HeaderSelectionListener extends SelectionAdapter {
489 private CommitItem.Order order;
491 private boolean reversed;
493 public HeaderSelectionListener(CommitItem.Order order) {
494 this.order = order;
497 @Override
498 public void widgetSelected(SelectionEvent e) {
499 TableColumn column = (TableColumn)e.widget;
500 Table table = column.getParent();
502 if (column == table.getSortColumn()) {
503 reversed = !reversed;
504 } else {
505 reversed = false;
507 table.setSortColumn(column);
509 Comparator<CommitItem> comparator;
510 if (reversed) {
511 comparator = order.descending();
512 table.setSortDirection(SWT.DOWN);
513 } else {
514 comparator = order;
515 table.setSortDirection(SWT.UP);
518 filesViewer.setComparator(new CommitViewerComparator(comparator));
523 class CommitItemSelectionListener extends SelectionAdapter {
525 public void widgetDefaultSelected(SelectionEvent e) {
526 IStructuredSelection selection = (IStructuredSelection) filesViewer.getSelection();
528 CommitItem commitItem = (CommitItem) selection.getFirstElement();
529 if (commitItem == null) {
530 return;
533 IProject project = commitItem.file.getProject();
534 RepositoryMapping mapping = RepositoryMapping.getMapping(project);
535 if (mapping == null) {
536 return;
538 Repository repository = mapping.getRepository();
540 Commit headCommit;
541 try {
542 headCommit = repository.mapCommit(Constants.HEAD);
543 } catch (IOException e1) {
544 headCommit = null;
546 if (headCommit == null) {
547 return;
550 GitProvider provider = (GitProvider) RepositoryProvider.getProvider(project);
551 GitFileHistoryProvider fileHistoryProvider = (GitFileHistoryProvider) provider.getFileHistoryProvider();
553 IFileHistory fileHistory = fileHistoryProvider.getFileHistoryFor(commitItem.file, 0, null);
555 IFileRevision baseFile = fileHistory.getFileRevision(headCommit.getCommitId().name());
556 IFileRevision nextFile = fileHistoryProvider.getWorkspaceFileRevision(commitItem.file);
558 ITypedElement base = new FileRevisionTypedElement(baseFile);
559 ITypedElement next = new FileRevisionTypedElement(nextFile);
561 GitCompareFileRevisionEditorInput input = new GitCompareFileRevisionEditorInput(base, next, null);
562 CompareUI.openCompareDialog(input);
567 @Override
568 protected void okPressed() {
569 commitMessage = commitText.getText();
570 author = authorText.getText().trim();
571 committer = committerText.getText().trim();
572 signedOff = signedOffButton.getSelection();
573 amending = amendingButton.getSelection();
575 Object[] checkedElements = filesViewer.getCheckedElements();
576 selectedFiles.clear();
577 for (Object obj : checkedElements)
578 selectedFiles.add(((CommitItem) obj).file);
580 if (commitMessage.trim().length() == 0) {
581 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorNoMessage, UIText.CommitDialog_ErrorMustEnterCommitMessage);
582 return;
585 boolean authorValid = false;
586 if (author.length() > 0) {
587 try {
588 new PersonIdent(author);
589 authorValid = true;
590 } catch (IllegalArgumentException e) {
591 authorValid = false;
594 if (!authorValid) {
595 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorInvalidAuthor, UIText.CommitDialog_ErrorInvalidAuthorSpecified);
596 return;
599 boolean committerValid = false;
600 if (committer.length() > 0) {
601 try {
602 new PersonIdent(committer);
603 committerValid = true;
604 } catch (IllegalArgumentException e) {
605 committerValid = false;
608 if (!committerValid) {
609 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorInvalidAuthor, UIText.CommitDialog_ErrorInvalidCommitterSpecified);
610 return;
613 if (selectedFiles.isEmpty() && !amending) {
614 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorNoItemsSelected, UIText.CommitDialog_ErrorNoItemsSelectedToBeCommitted);
615 return;
617 super.okPressed();
621 * Set the total list of changed resources, including additions and
622 * removals
624 * @param files potentially affected by a new commit
626 public void setFileList(ArrayList<IFile> files) {
627 items.clear();
628 for (IFile file : files) {
629 CommitItem item = new CommitItem();
630 item.status = getFileStatus(file);
631 item.file = file;
632 items.add(item);
636 @Override
637 protected void buttonPressed(int buttonId) {
638 if (IDialogConstants.SELECT_ALL_ID == buttonId) {
639 filesViewer.setAllChecked(true);
641 if (IDialogConstants.DESELECT_ALL_ID == buttonId) {
642 filesViewer.setAllChecked(false);
644 super.buttonPressed(buttonId);
648 * @return The author to set for the commit
650 public String getAuthor() {
651 return author;
655 * Pre-set author for the commit
657 * @param author
659 public void setAuthor(String author) {
660 this.author = author;
664 * @return The committer to set for the commit
666 public String getCommitter() {
667 return committer;
671 * Pre-set committer for the commit
673 * @param committer
675 public void setCommitter(String committer) {
676 this.committer = committer;
680 * Pre-set the previous author if amending the commit
682 * @param previousAuthor
684 public void setPreviousAuthor(String previousAuthor) {
685 this.previousAuthor = previousAuthor;
689 * @return whether to auto-add a signed-off line to the message
691 public boolean isSignedOff() {
692 return signedOff;
696 * Pre-set whether a signed-off line should be included in the commit
697 * message.
699 * @param signedOff
701 public void setSignedOff(boolean signedOff) {
702 this.signedOff = signedOff;
706 * @return whether the last commit is to be amended
708 public boolean isAmending() {
709 return amending;
713 * Pre-set whether the last commit is going to be amended
715 * @param amending
717 public void setAmending(boolean amending) {
718 this.amending = amending;
722 * Set the message from the previous commit for amending.
724 * @param string
726 public void setPreviousCommitMessage(String string) {
727 this.previousCommitMessage = string;
731 * Set whether the previous commit may be amended
733 * @param amendAllowed
735 public void setAmendAllowed(boolean amendAllowed) {
736 this.amendAllowed = amendAllowed;
739 @Override
740 protected int getShellStyle() {
741 return super.getShellStyle() | SWT.RESIZE;
745 class CommitItem {
746 String status;
748 IFile file;
750 public static enum Order implements Comparator<CommitItem> {
751 ByStatus() {
753 public int compare(CommitItem o1, CommitItem o2) {
754 return o1.status.compareTo(o2.status);
759 ByFile() {
761 public int compare(CommitItem o1, CommitItem o2) {
762 return o1.file.getProjectRelativePath().toString().
763 compareTo(o2.file.getProjectRelativePath().toString());
768 public Comparator<CommitItem> ascending() {
769 return this;
772 public Comparator<CommitItem> descending() {
773 return Collections.reverseOrder(this);
778 class CommitViewerComparator extends ViewerComparator {
780 public CommitViewerComparator(Comparator comparator){
781 super(comparator);
784 @SuppressWarnings("unchecked")
785 @Override
786 public int compare(Viewer viewer, Object e1, Object e2) {
787 return getComparator().compare(e1, e2);