package bndtools.editor.contents;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Version;
import bndtools.Plugin;
public class PackageInfoDialog extends TitleAreaDialog {
private final List<FileVersionTuple> packages;
private final Collection<FileVersionTuple> selection;
private boolean dontAsk = false;
private Table table;
private CheckboxTableViewer viewer;
/**
* Create the dialog.
*
* @param parentShell
* @param packages
*/
public PackageInfoDialog(Shell parentShell, List<FileVersionTuple> packages) {
super(parentShell);
setShellStyle(SWT.BORDER | SWT.CLOSE | SWT.RESIZE);
this.packages = packages;
selection = new ArrayList<FileVersionTuple>(packages.size());
selection.addAll(packages);
}
/**
* Create contents of the dialog.
*
* @param parent
*/
@SuppressWarnings("unused")
@Override
protected Control createDialogArea(Composite parent) {
setMessage(Messages.PackageInfoDialog_Message);
setTitle(Messages.PackageInfoDialog_Title);
Composite container = (Composite) super.createDialogArea(parent);
Composite composite = new Composite(container, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 10;
layout.marginWidth = 10;
composite.setLayout(layout);
table = new Table(composite, SWT.BORDER | SWT.CHECK | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
GridData gd_table = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2);
gd_table.heightHint = 100;
table.setLayoutData(gd_table);
table.setLinesVisible(true);
TableColumn tblclmnPackage = new TableColumn(table, SWT.NONE);
tblclmnPackage.setWidth(267);
tblclmnPackage.setText(Messages.PackageInfoDialog_ExportedPackage);
TableColumn tblclmnVersion = new TableColumn(table, SWT.NONE);
tblclmnVersion.setWidth(77);
tblclmnVersion.setText(Messages.PackageInfoDialog_Version);
Button btnCheckAll = new Button(composite, SWT.NONE);
btnCheckAll.setText(Messages.PackageInfoDialog_btnCheckAll_text);
btnCheckAll.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
btnCheckAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
selection.clear();
selection.addAll(packages);
viewer.setCheckedElements(selection.toArray());
validate();
}
});
Button btnUncheckAll = new Button(composite, SWT.NONE);
btnUncheckAll.setText(Messages.PackageInfoDialog_btnUncheckAll_text_1);
btnUncheckAll.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
btnUncheckAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
selection.clear();
viewer.setCheckedElements(selection.toArray());
validate();
}
});
final Button btnAlwaysGenerate = new Button(composite, SWT.CHECK);
btnAlwaysGenerate.setText(Messages.PackageInfoDialog_AlwaysGenerate);
viewer = new CheckboxTableViewer(table);
TableViewerColumn tblViewerClmnPackage = new TableViewerColumn(viewer, tblclmnPackage);
tblViewerClmnPackage.setLabelProvider(new PackageNameLabelProvider(table.getDisplay()));
TableViewerColumn tblViewerClmnVersion = new TableViewerColumn(viewer, tblclmnVersion);
tblViewerClmnVersion.setLabelProvider(new PackageVersionLabelProvider());
tblViewerClmnVersion.setEditingSupport(new VersionEditingSupport(viewer));
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setSorter(new ViewerSorter() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
FileVersionTuple f1 = (FileVersionTuple) e1;
FileVersionTuple f2 = (FileVersionTuple) e2;
return f1.compareTo(f2);
}
});
viewer.setInput(packages);
viewer.setCheckedElements(selection.toArray());
new Label(composite, SWT.NONE);
btnAlwaysGenerate.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
dontAsk = btnAlwaysGenerate.getSelection();
}
});
viewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
FileVersionTuple pkg = (FileVersionTuple) event.getElement();
if (event.getChecked())
selection.add(pkg);
else
selection.remove(pkg);
validate();
}
});
return container;
}
private void validate() {
String warning = null;
if (selection.size() < packages.size())
warning = Messages.PackageInfoDialog_Warning;
if (warning != null)
setMessage(warning, IMessageProvider.WARNING);
else
setMessage(Messages.PackageInfoDialog_Message);
}
/**
* Return the initial size of the dialog.
*/
@Override
protected Point getInitialSize() {
return new Point(500, 300);
}
public boolean isDontAsk() {
return dontAsk;
}
public Collection<FileVersionTuple> getSelectedPackageDirs() {
return new ArrayList<FileVersionTuple>(selection);
}
private class VersionEditingSupport extends EditingSupport {
private final CellEditor editor;
public VersionEditingSupport(TableViewer viewer) {
super(viewer);
final CellEditor textEditor = new TextCellEditor(viewer.getTable());
textEditor.setValidator(new ICellEditorValidator() {
@Override
public String isValid(Object value) {
String versionStr = String.valueOf(value);
Version v = Version.emptyVersion;
try {
v = Version.parseVersion(String.valueOf(value));
} catch (IllegalArgumentException iae) {
return MessageFormat.format(Messages.PackageInfoDialog_VersionInvalid, versionStr);
}
if (v == Version.emptyVersion) {
return Messages.PackageInfoDialog_VersionMissing;
}
return null;
}
});
textEditor.addListener(new ICellEditorListener() {
@Override
public void editorValueChanged(boolean oldValidState, boolean newValidState) {
if (newValidState) {
validate();
} else {
setMessage(textEditor.getErrorMessage(), IMessageProvider.ERROR);
}
}
@Override
public void cancelEditor() {
validate();
}
@Override
public void applyEditorValue() {
validate();
}
});
this.editor = textEditor;
}
@Override
protected boolean canEdit(Object element) {
return true;
}
@Override
protected CellEditor getCellEditor(Object element) {
return this.editor;
}
@Override
protected Object getValue(Object element) {
FileVersionTuple pkg = (FileVersionTuple) element;
return pkg.getVersion().toString();
}
@Override
protected void setValue(Object element, Object userInputValue) {
FileVersionTuple pkg = (FileVersionTuple) element;
pkg.setVersion(new Version(String.valueOf(userInputValue)));
getViewer().update(element, null);
}
}
private static class PackageNameLabelProvider extends StyledCellLabelProvider {
private final Image image;
public PackageNameLabelProvider(Device device) {
image = AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/package_obj.gif").createImage(device); //$NON-NLS-1$
}
@Override
public void update(ViewerCell cell) {
FileVersionTuple pkg = (FileVersionTuple) cell.getElement();
cell.setImage(image);
cell.setText(pkg.getName());
}
@Override
public void dispose() {
super.dispose();
image.dispose();
}
}
private static class PackageVersionLabelProvider extends StyledCellLabelProvider {
@Override
public void update(ViewerCell cell) {
FileVersionTuple pkg = (FileVersionTuple) cell.getElement();
StyledString label = new StyledString(pkg.getVersion().toString(), StyledString.COUNTER_STYLER);
cell.setText(label.getString());
cell.setStyleRanges(label.getStyleRanges());
}
}
public static class FileVersionTuple implements Comparable<FileVersionTuple> {
private final String name;
private final File file;
private Version version;
public FileVersionTuple(String pkgName, File file) {
this.name = pkgName;
this.file = file;
setVersion(new Version(1, 0, 0));
}
public String getName() {
return name;
}
public File getFile() {
return file;
}
public synchronized Version getVersion() {
return version;
}
public synchronized void setVersion(Version version) {
this.version = version;
}
public String formatVersionSpec() {
return "version " + getVersion().toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FileVersionTuple other = (FileVersionTuple) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(FileVersionTuple obj) {
return name.compareTo(obj.name);
}
}
}