/*******************************************************************************
* Copyright (c) 2011, 2012 GitHub Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Kevin Sawicki (GitHub Inc.) - initial API and implementation
* Daniel Megert <daniel_megert@ch.ibm.com> - handle RevisionSyntaxException
*******************************************************************************/
package org.eclipse.egit.ui.internal.commit;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Comparator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.GitLabelProvider;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.search.CommitSearchPage;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
/**
* Commit selection dialog
*/
public class CommitSelectionDialog extends FilteredItemsSelectionDialog {
private static final String COMMIT_SELECTION_DIALOG_SECTION = "CommitSelectionDialogSection"; //$NON-NLS-1$
private static class CommitLabelProvider extends GitLabelProvider {
public String getText(Object element) {
return getStyledText(element).getString();
}
public StyledString getStyledText(Object element) {
StyledString styled = new StyledString();
if (element instanceof RepositoryCommit) {
RepositoryCommit commit = (RepositoryCommit) element;
styled.append(commit.abbreviate());
styled.append(MessageFormat.format(
UIText.CommitSelectionDialog_SectionMessage, commit
.getRevCommit().getShortMessage()),
StyledString.QUALIFIER_STYLER);
styled.append(MessageFormat.format(
UIText.CommitSelectionDialog_SectionRepo,
commit.getRepositoryName()),
StyledString.DECORATIONS_STYLER);
} else if (element != null)
styled.append(element.toString());
return styled;
}
}
private CommitLabelProvider labelProvider;
/**
* Create commit selection dialog
*
* @param shell
* @param multi
*/
public CommitSelectionDialog(Shell shell, boolean multi) {
super(shell, multi);
setTitle(UIText.CommitSelectionDialog_Title);
setMessage(UIText.CommitSelectionDialog_Message);
labelProvider = new CommitLabelProvider();
setListLabelProvider(labelProvider);
setDetailsLabelProvider(new GitLabelProvider() {
@Override
public Image getImage(Object element) {
if (element instanceof RepositoryCommit) {
RepositoryCommit commit = (RepositoryCommit) element;
return super.getImage(commit.getRepository());
}
return super.getImage(element);
}
@Override
public String getText(Object element) {
if (element instanceof RepositoryCommit) {
RepositoryCommit commit = (RepositoryCommit) element;
return super.getText(commit.getRepository());
}
return super.getText(element);
}
});
setInitialPattern(Constants.HEAD, FULL_SELECTION);
}
protected Control createExtendedContentArea(Composite parent) {
Composite displayArea = new Composite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().applyTo(displayArea);
Link link = new Link(displayArea, SWT.NONE);
link.setText(UIText.CommitSelectionDialog_LinkSearch);
link.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
close();
NewSearchUI.openSearchDialog(PlatformUI.getWorkbench()
.getActiveWorkbenchWindow(), CommitSearchPage.ID);
}
});
return displayArea;
}
protected IDialogSettings getDialogSettings() {
IDialogSettings settings = Activator.getDefault().getDialogSettings();
IDialogSettings section = settings
.getSection(COMMIT_SELECTION_DIALOG_SECTION);
if (section == null)
section = settings.addNewSection(COMMIT_SELECTION_DIALOG_SECTION);
return section;
}
protected IStatus validateItem(Object item) {
return Status.OK_STATUS;
}
protected ItemsFilter createFilter() {
return new ItemsFilter() {
public boolean isSubFilter(ItemsFilter filter) {
return false;
}
public boolean matchItem(Object item) {
return true;
}
public boolean isConsistentItem(Object item) {
return true;
}
};
}
protected Comparator getItemsComparator() {
return new Comparator<RepositoryCommit>() {
public int compare(RepositoryCommit o1, RepositoryCommit o2) {
int compare = o1.getRepositoryName().compareToIgnoreCase(
o2.getRepositoryName());
if (compare == 0)
compare = o1.getRevCommit().compareTo(o2.getRevCommit());
return compare;
}
};
}
private Repository[] getRepositories() {
return org.eclipse.egit.core.Activator.getDefault()
.getRepositoryCache().getAllRepositories();
}
protected void fillContentProvider(AbstractContentProvider contentProvider,
ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
throws CoreException {
String pattern = itemsFilter.getPattern();
Repository[] repositories = getRepositories();
progressMonitor.beginTask(UIText.CommitSelectionDialog_TaskSearching,
repositories.length);
for (Repository repository : repositories) {
try {
ObjectId commitId;
if (ObjectId.isId(pattern))
commitId = ObjectId.fromString(pattern);
else
commitId = repository.resolve(itemsFilter.getPattern());
if (commitId != null) {
RevWalk walk = new RevWalk(repository);
walk.setRetainBody(true);
RevCommit commit = walk.parseCommit(commitId);
contentProvider.add(
new RepositoryCommit(repository, commit),
itemsFilter);
}
} catch (RevisionSyntaxException ignored) {
// Ignore and advance
} catch (IOException ignored) {
// Ignore and advance
}
progressMonitor.worked(1);
}
}
public String getElementName(Object item) {
return labelProvider.getText(item);
}
}