package com.dubture.composer.ui.parts.composer; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.ArrayUtils; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StyledCellLabelProvider; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.FormToolkit; import com.dubture.composer.ui.utils.WidgetFactory; import com.dubture.composer.ui.utils.WidgetHelper; import com.dubture.getcomposer.core.ComposerConstants; import com.dubture.getcomposer.core.ComposerPackage; import com.dubture.getcomposer.core.RepositoryPackage; import com.dubture.getcomposer.core.collection.Versions; import com.dubture.getcomposer.core.entities.Version; import com.dubture.getcomposer.packages.AsyncPackageDownloader; import com.dubture.getcomposer.packages.AsyncPackagistDownloader; import com.dubture.getcomposer.packages.PackageListenerInterface; public class VersionSuggestion { private static final int RECENT = 0; private static final int CUSTOM = 1; private FormToolkit toolkit = null; private WidgetFactory factory = null; private Text target; private Composite body; private Button recentMinor; private Button recentMajor; private Button noConstraint; private Map<String, Button> constraintButtons = new HashMap<String, Button>(); private boolean uiFinished = false; private boolean dataArrived = false; private RepositoryPackage pkg; private String majorVersion; private String minorVersion; private Version version = new Version(); private Version customVersion = new Version(); private int lastUpdate; private boolean updatingTarget = false; private TableViewer versions; private Combo stabilityOverride; private Group custom; private Composite right; private ComposerPackage composerPackage; public VersionSuggestion(String name, Composite parent, Text target, ComposerPackage composerPackage, FormToolkit toolkit) { this(name, parent, target, composerPackage, new WidgetFactory(toolkit)); this.toolkit = toolkit; } public VersionSuggestion(String name, Composite parent, Text target, ComposerPackage composerPackage, WidgetFactory factory) { this.factory = factory; this.target = target; this.composerPackage = composerPackage; // load package with versions AsyncPackageDownloader downloader = new AsyncPackagistDownloader(); downloader.addPackageListener(new PackageListenerInterface() { public void packageLoaded(final RepositoryPackage repositoryPackage) { dataArrived = true; pkg = repositoryPackage; // get major and minor Versions versions = pkg.getVersions(); majorVersion = versions.getRecentMajor(); minorVersion = versions.getRecentMinor(majorVersion); if (!updatingTarget) { updateUI(); } } public void errorOccured(Exception e) { e.printStackTrace(); } public void aborted(String url) {} }); downloader.loadPackage(name); create(parent, factory); } private void create(Composite parent, WidgetFactory factory) { body = factory.createComposite(parent); body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); body.setLayout(new GridLayout()); body.setBackground(parent.getBackground()); WidgetHelper.trimComposite(body, 0, 0, 0, 0, 0, 0); // suggestions Group suggestions = new Group(body, SWT.SHADOW_IN); suggestions.setText("Most Recent Version Suggestions"); suggestions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); suggestions.setLayout(new GridLayout(2, true)); suggestions.setBackgroundMode(SWT.INHERIT_DEFAULT); WidgetHelper.trimComposite(suggestions, 0, 0, 0, 0, 0, 5); // major recentMajor = factory.createButton(suggestions); recentMajor.setAlignment(SWT.CENTER); recentMajor.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); recentMajor.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { lastUpdate = RECENT; version.setVersion("~"+recentMajor.getData()); } }); // minor recentMinor = factory.createButton(suggestions); recentMinor.setAlignment(SWT.CENTER); recentMinor.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); recentMinor.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { lastUpdate = RECENT; version.setVersion("~"+recentMajor.getData() + "." + recentMinor.getData()); } }); // custom custom = new Group(body, SWT.SHADOW_ETCHED_IN); custom.setText("Custom"); custom.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); custom.setLayout(new GridLayout(2, false)); custom.setBackgroundMode(SWT.INHERIT_DEFAULT); WidgetHelper.trimComposite(custom, 0, 0, 0, 0, 0, 5); VersionController controller = new VersionController(); versions = new TableViewer(custom, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER); versions.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); versions.setContentProvider(controller); versions.setLabelProvider(controller); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false); gd.heightHint = 65; versions.getTable().setLayoutData(gd); versions.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { Object elem = ((IStructuredSelection)event.getSelection()).getFirstElement(); if (elem instanceof Version) { prepareCustomVersion(); Version v = (Version)elem; customVersion.setMajor(v.getMajor()); customVersion.setMinor(v.getMinor()); customVersion.setFix(v.getFix()); customVersion.setDevPosition(v.getDevPosition()); customVersion.setStability(v.getStability()); customVersion.setSuffix(v.getSuffix()); version.from(customVersion); } } }); versions.setComparator(new VersionSorter()); // constraints right = factory.createComposite(custom, SWT.NO_BACKGROUND); right.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); right.setLayout(new GridLayout(3, false)); right.setBackgroundMode(SWT.INHERIT_DEFAULT); WidgetHelper.trimComposite(right, -5, -5, -5, -5, 0, 0); Label constraintsLbl = factory.createLabel(right, SWT.NO_BACKGROUND | SWT.TRANSPARENT); constraintsLbl.setText("Constraints:"); constraintsLbl.setBackground(custom.getBackground()); constraintsLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); noConstraint = factory.createButton(right, SWT.RADIO | SWT.NO_BACKGROUND); noConstraint.setText("None"); noConstraint.setBackground(custom.getBackground()); noConstraint.setSelection(true); noConstraint.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (prepareCustomVersion()) { customVersion.setConstraint(""); version.from(customVersion); } } }); for (String constraint : new String[]{"~", ">", ">=", "!=", "<", ">="}) { Button c = factory.createButton(right, SWT.RADIO | SWT.TRANSPARENT); c.setText(constraint); c.setBackground(custom.getBackground()); c.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (prepareCustomVersion()) { customVersion.setConstraint(((Button)e.getSource()).getText()); version.from(customVersion); } } }); constraintButtons.put(constraint, c); } // Stability Override Label stabilityLbl = factory.createLabel(right); stabilityLbl.setText("Override Stability:"); stabilityLbl.setBackground(custom.getBackground()); gd = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1); gd.verticalIndent = 10; stabilityLbl.setLayoutData(gd); stabilityOverride = factory.createCombo(right, SWT.READ_ONLY | SWT.FLAT); stabilityOverride.setItems((String[])ArrayUtils.addAll(new String[]{""}, ComposerConstants.STABILITIES)); stabilityOverride.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); stabilityOverride.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (prepareCustomVersion()) { customVersion.setStabilityModifier(stabilityOverride.getItem(stabilityOverride.getSelectionIndex())); version.from(customVersion); } } }); uiFinished = true; updateUI(); // add listener to update target when version changes version.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { updateTarget(); } }); } private void updateUI() { Display.getDefault().syncExec(new Runnable() { public void run() { if (uiFinished) { recentMajor.setText("Major: " + (dataArrived && majorVersion != null ? "~" + majorVersion : "n.a.")); recentMajor.setEnabled(dataArrived && majorVersion != null); recentMajor.setData(majorVersion); recentMinor.setText("Minor: " + (dataArrived && majorVersion != null && minorVersion != null ? "~" + majorVersion + "." + minorVersion : "n.a.")); recentMinor.setEnabled(dataArrived && minorVersion != null); recentMinor.setData(minorVersion); custom.setEnabled(dataArrived); versions.getTable().setEnabled(dataArrived); stabilityOverride.setEnabled(dataArrived); // enable state for constraints for (Control child : right.getChildren()) { if (child instanceof Button) { ((Button)child).setEnabled(dataArrived); } } if (dataArrived) { versions.setInput(pkg.getVersions()); } } } }); } private void updateTarget() { updatingTarget = true; if (lastUpdate == RECENT || (version.getMajor() != null && !version.getMajor().isEmpty() && version.getMajor() != "null")) { String v = version.toString(); if (v != null) { target.setText(v); } } updatingTarget = false; } private boolean prepareCustomVersion() { if (updatingTarget) { return false; } if (lastUpdate == RECENT) { version.clear(); } lastUpdate = CUSTOM; return true; } public Composite getBody() { return body; } private class VersionController extends StyledCellLabelProvider implements IStructuredContentProvider { private Versions versions; public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { versions = (Versions)newInput; } public Object[] getElements(Object inputElement) { return versions.getDetailedVersions().toArray(); } public void update(ViewerCell cell) { Object obj = cell.getElement(); if (obj instanceof Version) { Version v = (Version)obj; StyledString styledString = new StyledString(v.toString()); styledString.append(" : " + v.getStability(), StyledString.QUALIFIER_STYLER); cell.setText(styledString.toString()); cell.setStyleRanges(styledString.getStyleRanges()); super.update(cell); } } } private class VersionSorter extends ViewerComparator{ public int compare(Viewer viewer, Object e1, Object e2) { if (e1 instanceof Version && e2 instanceof Version) { return ((Version) e1).compareTo((Version) e2) * -1; } return 0; } } }