Use generics for collections in commit dialog and import page
[egit/imyousuf.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / internal / dialogs / CommitDialog.java
blobe6bd02dd9f7bc6cb096800afdd2702c9dc256984
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.GitProvider;
63 import org.spearce.egit.core.internal.storage.GitFileHistoryProvider;
64 import org.spearce.egit.core.project.RepositoryMapping;
65 import org.spearce.egit.ui.UIText;
66 import org.spearce.egit.ui.internal.GitCompareFileRevisionEditorInput;
67 import org.spearce.jgit.lib.Commit;
68 import org.spearce.jgit.lib.Constants;
69 import org.spearce.jgit.lib.GitIndex;
70 import org.spearce.jgit.lib.PersonIdent;
71 import org.spearce.jgit.lib.Repository;
72 import org.spearce.jgit.lib.Tree;
73 import org.spearce.jgit.lib.TreeEntry;
74 import org.spearce.jgit.lib.GitIndex.Entry;
76 /**
77 * Dialog is shown to user when they request to commit files. Changes in the
78 * selected portion of the tree are shown.
80 public class CommitDialog extends Dialog {
82 class CommitContentProvider implements IStructuredContentProvider {
84 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
85 // Empty
88 public void dispose() {
89 // Empty
92 public Object[] getElements(Object inputElement) {
93 return items.toArray();
98 class CommitLabelProvider extends WorkbenchLabelProvider implements
99 ITableLabelProvider {
100 public String getColumnText(Object obj, int columnIndex) {
101 CommitItem item = (CommitItem) obj;
103 switch (columnIndex) {
104 case 0:
105 return item.status;
107 case 1:
108 return item.file.getProject().getName() + ": " //$NON-NLS-1$
109 + item.file.getProjectRelativePath();
111 default:
112 return null;
116 public Image getColumnImage(Object element, int columnIndex) {
117 if (columnIndex == 0)
118 return getImage(element);
119 return null;
123 ArrayList<CommitItem> items = new ArrayList<CommitItem>();
126 * @param parentShell
128 public CommitDialog(Shell parentShell) {
129 super(parentShell);
132 @Override
133 protected void createButtonsForButtonBar(Composite parent) {
134 createButton(parent, IDialogConstants.SELECT_ALL_ID, UIText.CommitDialog_SelectAll, false);
135 createButton(parent, IDialogConstants.DESELECT_ALL_ID, UIText.CommitDialog_DeselectAll, false);
137 createButton(parent, IDialogConstants.OK_ID, UIText.CommitDialog_Commit, true);
138 createButton(parent, IDialogConstants.CANCEL_ID,
139 IDialogConstants.CANCEL_LABEL, false);
142 Text commitText;
143 Text authorText;
144 Text committerText;
145 Button amendingButton;
146 Button signedOffButton;
148 CheckboxTableViewer filesViewer;
150 @Override
151 protected Control createDialogArea(Composite parent) {
152 Composite container = (Composite) super.createDialogArea(parent);
153 parent.getShell().setText(UIText.CommitDialog_CommitChanges);
155 GridLayout layout = new GridLayout(2, false);
156 container.setLayout(layout);
158 Label label = new Label(container, SWT.LEFT);
159 label.setText(UIText.CommitDialog_CommitMessage);
160 label.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, false).create());
162 commitText = new Text(container, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
163 commitText.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, true)
164 .hint(600, 200).create());
166 // allow to commit with ctrl-enter
167 commitText.addKeyListener(new KeyAdapter() {
168 public void keyPressed(KeyEvent arg0) {
169 if (arg0.keyCode == SWT.CR
170 && (arg0.stateMask & SWT.CONTROL) > 0) {
171 okPressed();
172 } else if (arg0.keyCode == SWT.TAB
173 && (arg0.stateMask & SWT.SHIFT) == 0) {
174 arg0.doit = false;
175 commitText.traverse(SWT.TRAVERSE_TAB_NEXT);
180 new Label(container, SWT.LEFT).setText(UIText.CommitDialog_Author);
181 authorText = new Text(container, SWT.BORDER);
182 authorText.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
183 if (author != null)
184 authorText.setText(author);
186 new Label(container, SWT.LEFT).setText(UIText.CommitDialog_Committer);
187 committerText = new Text(container, SWT.BORDER);
188 committerText.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
189 if (committer != null)
190 committerText.setText(committer);
191 committerText.addModifyListener(new ModifyListener() {
192 String oldCommitter = committerText.getText();
193 public void modifyText(ModifyEvent e) {
194 if (signedOffButton.getSelection()) {
195 // the commit message is signed
196 // the signature must be updated
197 String newCommitter = committerText.getText();
198 String oldSignOff = getSignedOff(oldCommitter);
199 String newSignOff = getSignedOff(newCommitter);
200 commitText.setText(replaceSignOff(commitText.getText(), oldSignOff, newSignOff));
201 oldCommitter = newCommitter;
206 amendingButton = new Button(container, SWT.CHECK);
207 if (amending) {
208 amendingButton.setSelection(amending);
209 amendingButton.setEnabled(false); // if already set, don't allow any changes
210 commitText.setText(previousCommitMessage);
211 authorText.setText(previousAuthor);
212 } else if (!amendAllowed) {
213 amendingButton.setEnabled(false);
215 amendingButton.addSelectionListener(new SelectionListener() {
216 boolean alreadyAdded = false;
217 public void widgetSelected(SelectionEvent arg0) {
218 if (alreadyAdded)
219 return;
220 if (amendingButton.getSelection()) {
221 alreadyAdded = true;
222 String curText = commitText.getText();
223 if (curText.length() > 0)
224 curText += "\n"; //$NON-NLS-1$
225 commitText.setText(curText + previousCommitMessage);
226 authorText.setText(previousAuthor);
230 public void widgetDefaultSelected(SelectionEvent arg0) {
231 // Empty
235 amendingButton.setText(UIText.CommitDialog_AmendPreviousCommit);
236 amendingButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, 1).create());
238 signedOffButton = new Button(container, SWT.CHECK);
239 signedOffButton.setSelection(signedOff);
240 signedOffButton.setText(UIText.CommitDialog_AddSOB);
241 signedOffButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, 1).create());
243 signedOffButton.addSelectionListener(new SelectionListener() {
244 public void widgetSelected(SelectionEvent arg0) {
245 String curText = commitText.getText();
246 if (signedOffButton.getSelection()) {
247 // add signed off line
248 commitText.setText(signOff(curText));
249 } else {
250 // remove signed off line
251 curText = replaceSignOff(curText, getSignedOff(), "");
252 if (curText.endsWith(Text.DELIMITER + Text.DELIMITER))
253 curText = curText.substring(0, curText.length() - Text.DELIMITER.length());
254 commitText.setText(curText);
258 public void widgetDefaultSelected(SelectionEvent arg0) {
259 // Empty
263 commitText.addModifyListener(new ModifyListener() {
264 public void modifyText(ModifyEvent e) {
265 updateSignedOffButton();
268 updateSignedOffButton();
270 Table resourcesTable = new Table(container, SWT.H_SCROLL | SWT.V_SCROLL
271 | SWT.FULL_SELECTION | SWT.MULTI | SWT.CHECK | SWT.BORDER);
272 resourcesTable.setLayoutData(GridDataFactory.fillDefaults().hint(600,
273 200).span(2,1).grab(true, true).create());
275 resourcesTable.addSelectionListener(new CommitItemSelectionListener());
277 resourcesTable.setHeaderVisible(true);
278 TableColumn statCol = new TableColumn(resourcesTable, SWT.LEFT);
279 statCol.setText(UIText.CommitDialog_Status);
280 statCol.setWidth(150);
281 statCol.addSelectionListener(new HeaderSelectionListener(CommitItem.Order.ByStatus));
283 TableColumn resourceCol = new TableColumn(resourcesTable, SWT.LEFT);
284 resourceCol.setText(UIText.CommitDialog_File);
285 resourceCol.setWidth(415);
286 resourceCol.addSelectionListener(new HeaderSelectionListener(CommitItem.Order.ByFile));
288 filesViewer = new CheckboxTableViewer(resourcesTable);
289 filesViewer.setContentProvider(new CommitContentProvider());
290 filesViewer.setLabelProvider(new CommitLabelProvider());
291 filesViewer.setInput(items);
292 filesViewer.setAllChecked(true);
293 filesViewer.getTable().setMenu(getContextMenu());
295 container.pack();
296 return container;
299 private void updateSignedOffButton() {
300 String curText = commitText.getText();
301 if (!curText.endsWith(Text.DELIMITER))
302 curText += Text.DELIMITER;
304 signedOffButton.setSelection(curText.indexOf(getSignedOff() + Text.DELIMITER) != -1);
307 private String getSignedOff() {
308 return getSignedOff(committerText.getText());
311 private String getSignedOff(String signer) {
312 return Constants.SIGNED_OFF_BY_TAG + signer;
315 private String signOff(String input) {
316 String output = input;
317 if (!output.endsWith(Text.DELIMITER))
318 output += Text.DELIMITER;
320 // if the last line is not a signed off (amend a commit), had a line break
321 if (!getLastLine(output).startsWith(Constants.SIGNED_OFF_BY_TAG))
322 output += Text.DELIMITER;
323 output += getSignedOff();
324 return output;
327 private String getLastLine(String input) {
328 String output = input;
329 int breakLength = Text.DELIMITER.length();
331 // remove last line break if exist
332 int lastIndexOfLineBreak = output.lastIndexOf(Text.DELIMITER);
333 if (lastIndexOfLineBreak != -1 && lastIndexOfLineBreak == output.length() - breakLength)
334 output = output.substring(0, output.length() - breakLength);
336 // get the last line
337 lastIndexOfLineBreak = output.lastIndexOf(Text.DELIMITER);
338 return lastIndexOfLineBreak == -1 ? output : output.substring(lastIndexOfLineBreak + breakLength, output.length());
341 private String replaceSignOff(String input, String oldSignOff, String newSignOff) {
342 assert input != null;
343 assert oldSignOff != null;
344 assert newSignOff != null;
346 String curText = input;
347 if (!curText.endsWith(Text.DELIMITER))
348 curText += Text.DELIMITER;
350 int indexOfSignOff = curText.indexOf(oldSignOff + Text.DELIMITER);
351 if (indexOfSignOff == -1)
352 return input;
354 return input.substring(0, indexOfSignOff) + newSignOff + input.substring(indexOfSignOff + oldSignOff.length(), input.length());
357 private Menu getContextMenu() {
358 Menu menu = new Menu(filesViewer.getTable());
359 MenuItem item = new MenuItem(menu, SWT.PUSH);
360 item.setText(UIText.CommitDialog_AddFileOnDiskToIndex);
361 item.addListener(SWT.Selection, new Listener() {
362 public void handleEvent(Event arg0) {
363 IStructuredSelection sel = (IStructuredSelection) filesViewer.getSelection();
364 if (sel.isEmpty()) {
365 return;
367 try {
368 ArrayList<GitIndex> changedIndexes = new ArrayList<GitIndex>();
369 for (Iterator<?> it = sel.iterator(); it.hasNext();) {
370 CommitItem commitItem = (CommitItem) it.next();
372 IProject project = commitItem.file.getProject();
373 RepositoryMapping map = RepositoryMapping.getMapping(project);
375 Repository repo = map.getRepository();
376 GitIndex index = null;
377 index = repo.getIndex();
378 Entry entry = index.getEntry(map.getRepoRelativePath(commitItem.file));
379 if (entry != null && entry.isModified(map.getWorkDir())) {
380 entry.update(new File(map.getWorkDir(), entry.getName()));
381 if (!changedIndexes.contains(index))
382 changedIndexes.add(index);
385 if (!changedIndexes.isEmpty()) {
386 for (GitIndex idx : changedIndexes) {
387 idx.write();
389 filesViewer.refresh(true);
391 } catch (IOException e) {
392 e.printStackTrace();
393 return;
398 return menu;
401 private static String getFileStatus(IFile file) {
402 String prefix = UIText.CommitDialog_StatusUnknown;
404 try {
405 RepositoryMapping repositoryMapping = RepositoryMapping
406 .getMapping(file.getProject());
408 Repository repo = repositoryMapping.getRepository();
409 GitIndex index = repo.getIndex();
410 Tree headTree = repo.mapTree(Constants.HEAD);
412 String repoPath = repositoryMapping.getRepoRelativePath(file);
413 TreeEntry headEntry = headTree.findBlobMember(repoPath);
414 boolean headExists = headTree.existsBlob(repoPath);
416 Entry indexEntry = index.getEntry(repoPath);
417 if (headEntry == null) {
418 prefix = UIText.CommitDialog_StatusAdded;
419 if (indexEntry.isModified(repositoryMapping.getWorkDir()))
420 prefix = UIText.CommitDialog_StatusAddedIndexDiff;
421 } else if (indexEntry == null) {
422 prefix = UIText.CommitDialog_StatusRemoved;
423 } else if (headExists
424 && !headEntry.getId().equals(indexEntry.getObjectId())) {
425 prefix = UIText.CommitDialog_StatusModified;
427 if (indexEntry.isModified(repositoryMapping.getWorkDir()))
428 prefix = UIText.CommitDialog_StatusModifiedIndexDiff;
429 } else if (!new File(repositoryMapping.getWorkDir(), indexEntry
430 .getName()).isFile()) {
431 prefix = UIText.CommitDialog_StatusRemovedNotStaged;
432 } else if (indexEntry.isModified(repositoryMapping.getWorkDir())) {
433 prefix = UIText.CommitDialog_StatusModifiedNotStaged;
436 } catch (Exception e) {
439 return prefix;
443 * @return The message the user entered
445 public String getCommitMessage() {
446 return commitMessage.replaceAll(Text.DELIMITER, "\n"); //$NON-NLS-1$;
450 * Preset a commit message. This might be for amending a commit.
451 * @param s the commit message
453 public void setCommitMessage(String s) {
454 this.commitMessage = s;
457 private String commitMessage = ""; //$NON-NLS-1$
458 private String author = null;
459 private String committer = null;
460 private String previousAuthor = null;
461 private boolean signedOff = false;
462 private boolean amending = false;
463 private boolean amendAllowed = true;
465 private ArrayList<IFile> selectedFiles = new ArrayList<IFile>();
466 private String previousCommitMessage = ""; //$NON-NLS-1$
469 * Pre-select suggested set of resources to commit
471 * @param items
473 public void setSelectedFiles(IFile[] items) {
474 Collections.addAll(selectedFiles, items);
478 * @return the resources selected by the user to commit.
480 public IFile[] getSelectedFiles() {
481 return selectedFiles.toArray(new IFile[0]);
484 class HeaderSelectionListener extends SelectionAdapter {
486 private CommitItem.Order order;
488 private boolean reversed;
490 public HeaderSelectionListener(CommitItem.Order order) {
491 this.order = order;
494 @Override
495 public void widgetSelected(SelectionEvent e) {
496 TableColumn column = (TableColumn)e.widget;
497 Table table = column.getParent();
499 if (column == table.getSortColumn()) {
500 reversed = !reversed;
501 } else {
502 reversed = false;
504 table.setSortColumn(column);
506 Comparator<CommitItem> comparator;
507 if (reversed) {
508 comparator = order.descending();
509 table.setSortDirection(SWT.DOWN);
510 } else {
511 comparator = order;
512 table.setSortDirection(SWT.UP);
515 filesViewer.setComparator(new CommitViewerComparator(comparator));
520 class CommitItemSelectionListener extends SelectionAdapter {
522 public void widgetDefaultSelected(SelectionEvent e) {
523 IStructuredSelection selection = (IStructuredSelection) filesViewer.getSelection();
525 CommitItem commitItem = (CommitItem) selection.getFirstElement();
526 if (commitItem == null) {
527 return;
530 IProject project = commitItem.file.getProject();
531 RepositoryMapping mapping = RepositoryMapping.getMapping(project);
532 if (mapping == null) {
533 return;
535 Repository repository = mapping.getRepository();
537 Commit headCommit;
538 try {
539 headCommit = repository.mapCommit(Constants.HEAD);
540 } catch (IOException e1) {
541 headCommit = null;
543 if (headCommit == null) {
544 return;
547 GitProvider provider = (GitProvider) RepositoryProvider.getProvider(project);
548 GitFileHistoryProvider fileHistoryProvider = (GitFileHistoryProvider) provider.getFileHistoryProvider();
550 IFileHistory fileHistory = fileHistoryProvider.getFileHistoryFor(commitItem.file, 0, null);
552 IFileRevision baseFile = fileHistory.getFileRevision(headCommit.getCommitId().name());
553 IFileRevision nextFile = fileHistoryProvider.getWorkspaceFileRevision(commitItem.file);
555 ITypedElement base = new FileRevisionTypedElement(baseFile);
556 ITypedElement next = new FileRevisionTypedElement(nextFile);
558 GitCompareFileRevisionEditorInput input = new GitCompareFileRevisionEditorInput(base, next, null);
559 CompareUI.openCompareDialog(input);
564 @Override
565 protected void okPressed() {
566 commitMessage = commitText.getText();
567 author = authorText.getText().trim();
568 committer = committerText.getText().trim();
569 signedOff = signedOffButton.getSelection();
570 amending = amendingButton.getSelection();
572 Object[] checkedElements = filesViewer.getCheckedElements();
573 selectedFiles.clear();
574 for (Object obj : checkedElements)
575 selectedFiles.add(((CommitItem) obj).file);
577 if (commitMessage.trim().length() == 0) {
578 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorNoMessage, UIText.CommitDialog_ErrorMustEnterCommitMessage);
579 return;
582 boolean authorValid = false;
583 if (author.length() > 0) {
584 try {
585 new PersonIdent(author);
586 authorValid = true;
587 } catch (IllegalArgumentException e) {
588 authorValid = false;
591 if (!authorValid) {
592 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorInvalidAuthor, UIText.CommitDialog_ErrorInvalidAuthorSpecified);
593 return;
596 boolean committerValid = false;
597 if (committer.length() > 0) {
598 try {
599 new PersonIdent(committer);
600 committerValid = true;
601 } catch (IllegalArgumentException e) {
602 committerValid = false;
605 if (!committerValid) {
606 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorInvalidAuthor, UIText.CommitDialog_ErrorInvalidCommitterSpecified);
607 return;
610 if (selectedFiles.isEmpty() && !amending) {
611 MessageDialog.openWarning(getShell(), UIText.CommitDialog_ErrorNoItemsSelected, UIText.CommitDialog_ErrorNoItemsSelectedToBeCommitted);
612 return;
614 super.okPressed();
618 * Set the total list of changed resources, including additions and
619 * removals
621 * @param files potentially affected by a new commit
623 public void setFileList(ArrayList<IFile> files) {
624 items.clear();
625 for (IFile file : files) {
626 CommitItem item = new CommitItem();
627 item.status = getFileStatus(file);
628 item.file = file;
629 items.add(item);
633 @Override
634 protected void buttonPressed(int buttonId) {
635 if (IDialogConstants.SELECT_ALL_ID == buttonId) {
636 filesViewer.setAllChecked(true);
638 if (IDialogConstants.DESELECT_ALL_ID == buttonId) {
639 filesViewer.setAllChecked(false);
641 super.buttonPressed(buttonId);
645 * @return The author to set for the commit
647 public String getAuthor() {
648 return author;
652 * Pre-set author for the commit
654 * @param author
656 public void setAuthor(String author) {
657 this.author = author;
661 * @return The committer to set for the commit
663 public String getCommitter() {
664 return committer;
668 * Pre-set committer for the commit
670 * @param committer
672 public void setCommitter(String committer) {
673 this.committer = committer;
677 * Pre-set the previous author if amending the commit
679 * @param previousAuthor
681 public void setPreviousAuthor(String previousAuthor) {
682 this.previousAuthor = previousAuthor;
686 * @return whether to auto-add a signed-off line to the message
688 public boolean isSignedOff() {
689 return signedOff;
693 * Pre-set whether a signed-off line should be included in the commit
694 * message.
696 * @param signedOff
698 public void setSignedOff(boolean signedOff) {
699 this.signedOff = signedOff;
703 * @return whether the last commit is to be amended
705 public boolean isAmending() {
706 return amending;
710 * Pre-set whether the last commit is going to be amended
712 * @param amending
714 public void setAmending(boolean amending) {
715 this.amending = amending;
719 * Set the message from the previous commit for amending.
721 * @param string
723 public void setPreviousCommitMessage(String string) {
724 this.previousCommitMessage = string;
728 * Set whether the previous commit may be amended
730 * @param amendAllowed
732 public void setAmendAllowed(boolean amendAllowed) {
733 this.amendAllowed = amendAllowed;
736 @Override
737 protected int getShellStyle() {
738 return super.getShellStyle() | SWT.RESIZE;
742 class CommitItem {
743 String status;
745 IFile file;
747 public static enum Order implements Comparator<CommitItem> {
748 ByStatus() {
750 public int compare(CommitItem o1, CommitItem o2) {
751 return o1.status.compareTo(o2.status);
756 ByFile() {
758 public int compare(CommitItem o1, CommitItem o2) {
759 return o1.file.getProjectRelativePath().toString().
760 compareTo(o2.file.getProjectRelativePath().toString());
765 public Comparator<CommitItem> ascending() {
766 return this;
769 public Comparator<CommitItem> descending() {
770 return Collections.reverseOrder(this);
775 class CommitViewerComparator extends ViewerComparator {
777 public CommitViewerComparator(Comparator comparator){
778 super(comparator);
781 @SuppressWarnings("unchecked")
782 @Override
783 public int compare(Viewer viewer, Object e1, Object e2) {
784 return getComparator().compare(e1, e2);