/*******************************************************************************
* Copyright (c) 2006-2007, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
******************************************************************************/
package org.eclipse.buckminster.jnlp.wizard.install;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.buckminster.jnlp.MaterializationConstants;
import org.eclipse.buckminster.jnlp.MaterializationUtils;
import org.eclipse.buckminster.jnlp.Messages;
import org.eclipse.buckminster.jnlp.distroprovider.DistroVariant;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
/**
* @author Karel Brezina
*
*/
public class SelectDistroPage extends InstallWizardPage
{
private class VariantViewerComparator extends ViewerComparator
{
private int m_column = -1;
private int m_direction = SWT.NONE;
@Override
public int compare(Viewer viewer, Object e1, Object e2)
{
if(m_direction == SWT.NONE)
return 0;
String ai = getColumnValueFromVariant((DistroVariant)e1, m_column);
String bi = getColumnValueFromVariant((DistroVariant)e2, m_column);
return m_direction == SWT.UP
? safeStringComarator(ai, bi)
: safeStringComarator(bi, ai);
}
public void setSortColumn(int column)
{
if(column == m_column)
{
// Same column as last sort; toggle the direction
switch(m_direction)
{
case SWT.NONE:
m_direction = SWT.UP;
break;
case SWT.UP:
m_direction = SWT.DOWN;
break;
default:
m_direction = SWT.NONE;
}
}
else
{
// New column; do an ascending sort
m_column = column;
m_direction = SWT.UP;
}
m_variantsTableViewer.getTable().setSortColumn(m_columns.get(m_column));
m_variantsTableViewer.getTable().setSortDirection(m_direction);
}
@Override
public void sort(Viewer viewer, Object[] elements)
{
if(m_direction != SWT.NONE)
super.sort(viewer, elements);
}
private int safeStringComarator(String arg0, String arg1)
{
if(arg0 == null && arg1 == null)
return 0;
if(arg0 == null)
return -1;
if(arg1 == null)
return 1;
return arg0.compareTo(arg1);
}
}
private static final String DISTRO_COMPATIBLE = "1"; //$NON-NLS-1$
private static final String DISTRO_BROKEN = "-1"; //$NON-NLS-1$
private static final String DISTRO_INCOMPATIBLE = "0"; //$NON-NLS-1$
private static final String ICON_COMPATIBLE = "distro.compatible.gif"; //$NON-NLS-1$
private static final String ICON_INCOMPATIBLE = "distro.incompatible.gif"; //$NON-NLS-1$
private static final String ICON_BROKEN = "distro.broken.gif"; //$NON-NLS-1$
private static final String IMAGE_BOX_COMPATIBLE = "box.enabled.compatible.png"; //$NON-NLS-1$
private static final String IMAGE_BOX_INCOMPATIBLE = "box.enabled.incompatible.png"; //$NON-NLS-1$
private static final String IMAGE_BOX_BROKEN = "box.disabled.broken.png"; //$NON-NLS-1$
private static final String IMAGE_BOX_DISABLED = "box.disabled.png"; //$NON-NLS-1$
private Font m_boldFont;
private Font m_italicFont;
private Color m_orangeColor;
private Color m_redColor;
private final Image m_iconCompatible;
private final Image m_iconIncompatible;
private final Image m_iconBroken;
private final Image m_imageBoxCompatible;
private final Image m_imageBoxIncompatible;
private final Image m_imageBoxBroken;
private final Image m_imageBoxDisabled;
private Composite m_topComposite;
private StackLayout m_stackLayout;
private Composite m_noDistroPageComposite;
private Label m_noDistroLabel;
private Composite m_pageComposite;
private Button m_incompatibleButton;
private Button m_brokenButton;
private TableViewer m_variantsTableViewer;
private List<TableColumn> m_columns;
private Label m_selectionBoxLabel;
private Label m_selectionHeadingLabel;
private Composite m_selectionComposite;
private Composite m_selectionDetailsComposite;
private static final String UNSPECIFIED = Messages.unspecified;
private List<DistroVariant> m_data;
private boolean m_initialized = false;
public SelectDistroPage()
{
super(MaterializationConstants.STEP_SELECT_DISTRO, Messages.select_distro,
Messages.select_from_the_available_packagings_of_this_stack, null);
m_iconCompatible = MaterializationUtils.getImage(ICON_COMPATIBLE);
m_iconIncompatible = MaterializationUtils.getImage(ICON_INCOMPATIBLE);
m_iconBroken = MaterializationUtils.getImage(ICON_BROKEN);
m_imageBoxCompatible = MaterializationUtils.getImage(IMAGE_BOX_COMPATIBLE);
m_imageBoxIncompatible = MaterializationUtils.getImage(IMAGE_BOX_INCOMPATIBLE);
m_imageBoxBroken = MaterializationUtils.getImage(IMAGE_BOX_BROKEN);
m_imageBoxDisabled = MaterializationUtils.getImage(IMAGE_BOX_DISABLED);
}
public void createControl(Composite parent)
{
m_topComposite = new Composite(parent, SWT.NONE);
m_stackLayout = new StackLayout();
m_topComposite.setLayout(m_stackLayout);
m_noDistroPageComposite = new Composite(m_topComposite, SWT.NONE);
m_noDistroPageComposite.setLayout(new GridLayout(1, false));
m_noDistroLabel = new Label(m_noDistroPageComposite, SWT.WRAP);
m_noDistroLabel
.setText(Messages.sorry_the_publisher_of_this_stack_hasnt_packaged_it_in_a_distro_available_for_download);
FontData[] fontData = m_noDistroLabel.getFont().getFontData();
fontData[0].setStyle(SWT.BOLD);
m_boldFont = new Font(getShell().getDisplay(), fontData);
fontData[0].setStyle(SWT.ITALIC);
m_italicFont = new Font(getShell().getDisplay(), fontData);
m_orangeColor = new Color(getShell().getDisplay(), 255, 161, 68);
m_redColor = getShell().getDisplay().getSystemColor(SWT.COLOR_RED);
m_noDistroLabel.setFont(m_boldFont);
m_pageComposite = new Composite(m_topComposite, SWT.NONE);
m_pageComposite.setLayout(new GridLayout(1, false));
Label label = new Label(m_pageComposite, SWT.NONE);
label.setText(Messages.the_following_distros_appear_to_be_compatible_with_your_platform_with_colon);
label.setFont(m_boldFont);
Composite flagsComposite = new Composite(m_pageComposite, SWT.NONE);
GridLayout gridLayout = new GridLayout(2, false);
gridLayout.marginWidth = 0;
flagsComposite.setLayout(gridLayout);
label = new Label(flagsComposite, SWT.NONE);
label.setText(Messages.show);
GridData gridData = new GridData();
gridData.verticalSpan = 2;
gridData.verticalAlignment = SWT.TOP;
label.setLayoutData(gridData);
m_incompatibleButton = new Button(flagsComposite, SWT.CHECK);
m_incompatibleButton.setText(Messages.incompatible_packagings);
m_brokenButton = new Button(flagsComposite, SWT.CHECK);
m_brokenButton.setText(Messages.broken_packagings);
SelectionListener distroFilterListener = new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent arg0)
{
initializeTable();
}
};
m_incompatibleButton.addSelectionListener(distroFilterListener);
m_brokenButton.addSelectionListener(distroFilterListener);
final Table variantsTable = new Table(m_pageComposite, SWT.BORDER | SWT.FULL_SELECTION);
variantsTable.setLayoutData(new GridData(GridData.FILL_BOTH));
variantsTable.setHeaderVisible(true);
variantsTable.setLinesVisible(true);
m_variantsTableViewer = new TableViewer(variantsTable);
m_variantsTableViewer.setContentProvider(new IStructuredContentProvider()
{
public void dispose()
{
// nothing to dispose
}
@SuppressWarnings("unchecked")
public Object[] getElements(Object inputElement)
{
return ((List<DistroVariant>)inputElement).toArray(new DistroVariant[0]);
}
public void inputChanged(Viewer arg0, Object arg1, Object arg2)
{
// nothing to do
}
});
m_variantsTableViewer.setLabelProvider(new ITableLabelProvider()
{
private List<ILabelProviderListener> m_listeners = new ArrayList<ILabelProviderListener>();
public void addListener(ILabelProviderListener arg0)
{
m_listeners.add(arg0);
}
public void dispose()
{
// nothing to dispose
}
public Image getColumnImage(Object element, int columnIndex)
{
if(columnIndex == 0)
{
String status = getColumnValueFromVariant((DistroVariant)element, columnIndex);
return DISTRO_COMPATIBLE.equals(status)
? m_iconCompatible
: (DISTRO_INCOMPATIBLE.equals(status)
? m_iconIncompatible
: m_iconBroken);
}
return null;
}
public String getColumnText(Object element, int columnIndex)
{
if(columnIndex > 0)
return getColumnValueFromVariant((DistroVariant)element, columnIndex);
return null;
}
public boolean isLabelProperty(Object arg0, String arg1)
{
return false;
}
public void removeListener(ILabelProviderListener arg0)
{
m_listeners.remove(arg0);
}
});
m_variantsTableViewer.setComparator(new VariantViewerComparator());
m_columns = new ArrayList<TableColumn>();
TableColumn column = new TableColumn(variantsTable, SWT.NONE);
column.setText(Messages.compatible);
column.setAlignment(SWT.CENTER);
m_columns.add(column);
column = new TableColumn(variantsTable, SWT.NONE);
column.setText(Messages.CPU_architecture);
m_columns.add(column);
column = new TableColumn(variantsTable, SWT.NONE);
column.setText(Messages.operating_system);
m_columns.add(column);
column = new TableColumn(variantsTable, SWT.NONE);
column.setText(Messages.windowing_system);
m_columns.add(column);
column = new TableColumn(variantsTable, SWT.NONE);
column.setText(Messages.other_releases);
m_columns.add(column);
column = new TableColumn(variantsTable, SWT.NONE);
column.setText(Messages.language);
m_columns.add(column);
SelectionListener columnSelectionListener = new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent arg0)
{
((VariantViewerComparator)m_variantsTableViewer.getComparator()).setSortColumn(m_columns
.indexOf(arg0.widget));
m_variantsTableViewer.refresh();
packColumns();
selectFirstRow();
}
};
for(TableColumn col : m_columns)
col.addSelectionListener(columnSelectionListener);
variantsTable.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent arg0)
{
TableItem item = (TableItem)arg0.item;
DistroVariant variant = (DistroVariant)item.getData();
for(Control control : m_selectionDetailsComposite.getChildren())
control.dispose();
Label selectionDetailsLabel = new Label(m_selectionDetailsComposite, SWT.NONE);
selectionDetailsLabel.setFont(m_boldFont);
String variantStatus = getColumnValueFromVariant(variant, 0);
if(DISTRO_COMPATIBLE.equals(variantStatus))
{
m_selectionBoxLabel.setImage(m_imageBoxCompatible);
if(variant.isSimplePackaging())
{
m_selectionHeadingLabel.setText(Messages.simple_packaging_with_colon);
selectionDetailsLabel.setText(Messages.unspecified_in_brackets);
}
else
{
m_selectionHeadingLabel.setText(Messages.distro_variant_for_with_colon);
selectionDetailsLabel.setText(variant.getPlatformString());
}
}
else if(DISTRO_INCOMPATIBLE.equals(variantStatus))
{
m_selectionBoxLabel.setImage(m_imageBoxIncompatible);
m_selectionHeadingLabel.setText(Messages.incompatible_distro_variant_for_with_colon);
selectionDetailsLabel.dispose();
addSelectionDetailsPlatformLabel(variant.getArch(), variant.isArchCompatible());
addSelectionDetailsPlatformLabel(variant.getOS(), variant.isOSCompatible());
addSelectionDetailsPlatformLabel(variant.getWS(), variant.isWSCompatible());
addSelectionDetailsPlatformLabel(variant.getRelease(), variant.isReleaseCompatible());
addSelectionDetailsPlatformLabel(variant.getNL(), variant.isNLCompatible());
}
else if(DISTRO_BROKEN.equals(variantStatus))
{
m_selectionBoxLabel.setImage(m_imageBoxBroken);
m_selectionHeadingLabel.setText(Messages.distro_broken_not_downloadable_with_colon);
selectionDetailsLabel.setText(Messages.publisher_attention_needed_in_brackets);
selectionDetailsLabel.setFont(null);
}
else
{
m_selectionBoxLabel.setImage(m_imageBoxDisabled);
m_selectionHeadingLabel.setText(Messages.no_selected_packaging);
selectionDetailsLabel.setText(""); //$NON-NLS-1$
}
getContainer().updateButtons();
m_selectionDetailsComposite.layout();
m_selectionComposite.pack();
m_selectionComposite.layout();
}
});
m_selectionComposite = new Composite(m_pageComposite, SWT.NONE);
gridLayout = new GridLayout(2, false);
gridLayout.marginHeight = gridLayout.marginWidth = 0;
m_selectionComposite.setLayout(gridLayout);
m_selectionBoxLabel = new Label(m_selectionComposite, SWT.NONE);
Composite selectionDetailsComposite = new Composite(m_selectionComposite, SWT.NONE);
gridLayout = new GridLayout(1, false);
gridLayout.marginHeight = gridLayout.marginWidth = 0;
selectionDetailsComposite.setLayout(gridLayout);
m_selectionHeadingLabel = new Label(selectionDetailsComposite, SWT.NONE);
m_selectionDetailsComposite = new Composite(selectionDetailsComposite, SWT.NONE);
RowLayout rowLayout = new RowLayout();
rowLayout.marginLeft = 10;
rowLayout.justify = true;
rowLayout.spacing = 0;
rowLayout.wrap = false;
m_selectionDetailsComposite.setLayout(rowLayout);
setControl(m_topComposite);
}
@Override
public boolean isPageComplete()
{
if(isCurrentPage())
{
if(getInstallWizard().getDistroVariants() == null || getInstallWizard().getDistroVariants().size() == 0)
return false;
TableItem[] selection = m_variantsTableViewer.getTable().getSelection();
if(selection != null && selection.length == 1)
{
DistroVariant variant = (DistroVariant)selection[0].getData();
if(variant.isBroken())
return false;
return true;
}
}
else if(getInstallWizard().getDistro() != null)
return true;
return false;
}
@Override
public boolean performPageCommit()
{
if(isCurrentPage())
{
TableItem[] selection = m_variantsTableViewer.getTable().getSelection();
DistroVariant variant = (DistroVariant)selection[0].getData();
getInstallWizard().retrieveDistro(variant.getDistroId());
}
return true;
}
@Override
protected void beforeDisplaySetup()
{
if(getInstallWizard().getDistroVariants() == null || getInstallWizard().getDistroVariants().size() == 0)
{
// dynamic width of m_noDistroLabel
GridData layoutData = (GridData)m_noDistroLabel.getLayoutData();
layoutData.widthHint = m_noDistroLabel.getShell().getSize().x - 20;
m_noDistroPageComposite.layout();
m_stackLayout.topControl = m_noDistroPageComposite;
m_topComposite.layout();
}
else if(!m_initialized)
{
initializeTable();
setupFilters();
m_pageComposite.layout();
m_stackLayout.topControl = m_pageComposite;
m_topComposite.layout();
}
// distros are selected here
getInstallWizard().setDistro(null);
}
private void addSelectionDetailsPlatformLabel(String property, boolean isCompatible)
{
if(property != null)
{
if(m_selectionDetailsComposite.getChildren().length > 0)
addSelectionDetailsPlatformLabelSeparator();
Label label = new Label(m_selectionDetailsComposite, SWT.NONE);
label.setFont(m_boldFont);
label.setText(property);
if(!isCompatible)
label.setForeground(m_redColor);
}
}
private void addSelectionDetailsPlatformLabelSeparator()
{
Label comma = new Label(m_selectionDetailsComposite, SWT.NONE);
comma.setFont(m_boldFont);
comma.setText(", "); //$NON-NLS-1$
}
private String getColumnValueFromVariant(DistroVariant variant, int column)
{
if(column > 0 && variant.isSimplePackaging())
return UNSPECIFIED;
switch(column)
{
case 0:
return (variant.isBroken()
? DISTRO_BROKEN
: (variant.isCompatible()
? DISTRO_COMPATIBLE
: DISTRO_INCOMPATIBLE));
case 1:
return variant.getArch();
case 2:
return variant.getOS();
case 3:
return variant.getWS();
case 4:
return variant.getRelease();
case 5:
return variant.getNL();
default:
throw new IllegalArgumentException(NLS.bind(Messages.column_number_0_does_not_exist, Integer
.valueOf(column)));
}
}
private void initializeTable()
{
m_data = new ArrayList<DistroVariant>();
for(DistroVariant variant : getInstallWizard().getDistroVariants())
{
if(!variant.isCompatible() && !variant.isBroken() && !m_incompatibleButton.getSelection()
|| variant.isBroken() && !m_brokenButton.getSelection())
continue;
m_data.add(variant);
}
m_variantsTableViewer.setInput(m_data);
m_variantsTableViewer.refresh();
packColumns();
selectFirstRow();
setTableItemFontAndColor();
m_initialized = true;
}
private void packColumns()
{
m_variantsTableViewer.getTable().setRedraw(false);
setTableItemFontAndColor();
for(TableColumn col : m_columns)
col.pack();
m_variantsTableViewer.getTable().setRedraw(true);
}
private void selectFirstRow()
{
Table table = m_variantsTableViewer.getTable();
if(table.getItems().length > 0)
{
table.setSelection(0);
table.showSelection();
Event event = new Event();
event.item = table.getItem(0);
table.notifyListeners(SWT.Selection, event);
}
}
private void setTableItemFontAndColor()
{
TableItem[] items = m_variantsTableViewer.getTable().getItems();
for(TableItem item : items)
{
DistroVariant variant = (DistroVariant)item.getData();
if(variant.isBroken())
item.setForeground(m_orangeColor);
else
item.setForeground(null);
if(variant.isSimplePackaging())
item.setFont(m_italicFont);
else
item.setFont(null);
}
}
private void setupFilters()
{
boolean compatible = false;
boolean incompatible = false;
boolean broken = false;
for(DistroVariant variant : getInstallWizard().getDistroVariants())
{
if(variant.isCompatible() && !variant.isBroken())
compatible = true;
if(!variant.isCompatible() && !variant.isBroken())
incompatible = true;
if(variant.isBroken())
broken = true;
}
if(!incompatible)
m_incompatibleButton.setEnabled(false);
if(!broken)
m_brokenButton.setEnabled(false);
if(!compatible)
{
if(incompatible)
{
m_incompatibleButton.setSelection(true);
m_incompatibleButton.notifyListeners(SWT.Selection, new Event());
}
else if(broken)
{
m_brokenButton.setSelection(true);
m_brokenButton.notifyListeners(SWT.Selection, new Event());
}
}
}
}