/*******************************************************************************
* Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
* and other copyright owners as documented in the project's IP log.
*
* 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:
* Robin Rosenberg - Refactoring from CheckoutCommand
*******************************************************************************/
package org.eclipse.egit.ui.internal.dialogs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.egit.ui.internal.CommonUtils;
import org.eclipse.egit.ui.internal.GitLabelProvider;
import org.eclipse.egit.ui.internal.components.CachedCheckboxTreeViewer;
import org.eclipse.egit.ui.internal.components.FilteredCheckboxTree;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.progress.WorkbenchJob;
/**
* Allows to display some Branches for selection
* <p>
* In case of multi-selection, a checkbox tree is shown including a pattern
* filter, while in case of single selection, a simple table is used supporting
* double-click
*
* @param <T>
* the type of node; either {@link Ref} or and {@link IAdaptable} for
* {@link Ref}
*/
public class BranchSelectionDialog<T> extends MessageDialog {
private final List<T> nodes;
private TableViewer branchesList;
private FilteredCheckboxTree fTree;
private List<T> selected = new ArrayList<T>();
private final int style;
private final boolean multiMode;
/**
* @param parentShell
* @param nodes
* @param title
* @param message
* @param style
* only {@link SWT#SINGLE} and {@link SWT#MULTI} are supported
*/
public BranchSelectionDialog(Shell parentShell, List<T> nodes, String title,
String message, int style) {
super(parentShell, title, null, message, MessageDialog.QUESTION,
new String[] { IDialogConstants.OK_LABEL,
IDialogConstants.CANCEL_LABEL }, 0);
this.nodes = nodes;
this.style = style;
this.multiMode = (this.style & SWT.MULTI) > 0;
}
@Override
protected boolean isResizable() {
return true;
}
@Override
protected Control createCustomArea(Composite parent) {
Composite area = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).span(2, 1)
.applyTo(area);
area.setLayout(new GridLayout(1, false));
if (multiMode) {
fTree = new FilteredCheckboxTree(area, null, SWT.NONE,
new PatternFilter()) {
/*
* Overridden to check page when refreshing is done.
*/
protected WorkbenchJob doCreateRefreshJob() {
WorkbenchJob refreshJob = super.doCreateRefreshJob();
refreshJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
if (event.getResult().isOK()) {
getDisplay().asyncExec(new Runnable() {
public void run() {
checkPage();
}
});
}
}
});
return refreshJob;
}
};
CachedCheckboxTreeViewer viewer = fTree.getCheckboxTreeViewer();
GridDataFactory.fillDefaults().grab(true, true).applyTo(fTree);
viewer.setContentProvider(new ITreeContentProvider() {
public void inputChanged(Viewer actViewer, Object oldInput,
Object newInput) {
// nothing
}
public void dispose() {
// nothing
}
public boolean hasChildren(Object element) {
return false;
}
public Object getParent(Object element) {
return null;
}
public Object[] getElements(Object inputElement) {
return ((List) inputElement).toArray();
}
public Object[] getChildren(Object parentElement) {
return null;
}
});
viewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
checkPage();
}
});
viewer.setLabelProvider(new GitLabelProvider());
viewer.setComparator(new ViewerComparator(
CommonUtils.STRING_ASCENDING_COMPARATOR));
viewer.setInput(nodes);
} else {
branchesList = new TableViewer(area, this.style | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, true)
.applyTo(branchesList.getControl());
branchesList.setContentProvider(ArrayContentProvider.getInstance());
branchesList.setLabelProvider(new GitLabelProvider());
branchesList.setComparator(new ViewerComparator(
CommonUtils.STRING_ASCENDING_COMPARATOR));
branchesList.setInput(nodes);
branchesList
.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
checkPage();
}
});
branchesList.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
buttonPressed(OK);
}
});
}
return area;
}
private void checkPage() {
if (multiMode)
getButton(OK).setEnabled(
fTree.getCheckboxTreeViewer().getCheckedLeafCount() > 0);
else
getButton(OK).setEnabled(!branchesList.getSelection().isEmpty());
}
@SuppressWarnings("unchecked")
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == OK) {
if (multiMode) {
selected.clear();
Object[] checked = fTree.getCheckboxTreeViewer()
.getCheckedElements();
for (Object o : checked) {
selected.add((T) o);
}
} else {
selected = ((IStructuredSelection) branchesList.getSelection())
.toList();
}
}
super.buttonPressed(buttonId);
}
@Override
public void create() {
super.create();
getButton(OK).setEnabled(false);
}
/**
* @return the selected entry (single mode)
*/
public T getSelectedNode() {
if (selected.isEmpty())
return null;
return selected.get(0);
}
/**
* @return the selected entries (multi mode)
*/
public List<T> getSelectedNodes() {
return selected;
}
}