Java tutorial
/******************************************************************************* * Copyright (c) 2014 Mentor Graphics and others. * 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: * Mentor Graphics - initial API and implementation *******************************************************************************/ package com.codesourcery.internal.installer.ui.pages; import java.net.URI; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; 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.graphics.Point; import org.eclipse.swt.graphics.RGB; 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.Display; import org.eclipse.swt.widgets.ExpandBar; import org.eclipse.swt.widgets.ExpandItem; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import com.codesourcery.installer.IInstallConsoleProvider; import com.codesourcery.installer.IInstallData; import com.codesourcery.installer.IInstallDescription; import com.codesourcery.installer.IInstallMode; import com.codesourcery.installer.Installer; import com.codesourcery.installer.console.ConsoleListPrompter; import com.codesourcery.installer.ui.IInstallComponent; import com.codesourcery.installer.ui.IInstallSummaryProvider; import com.codesourcery.installer.ui.InstallWizardPage; import com.codesourcery.internal.installer.IInstallConstants; import com.codesourcery.internal.installer.IInstallPlan; import com.codesourcery.internal.installer.IInstallRepositoryListener; import com.codesourcery.internal.installer.IInstallerImages; import com.codesourcery.internal.installer.InstallMessages; import com.codesourcery.internal.installer.RepositoryManager; import com.codesourcery.internal.installer.ui.SpinnerProgress; import com.codesourcery.internal.installer.ui.UIUtils; /** * Page to show components for the install. Optional components can be selected. * This page supports console. */ public class ComponentsPage extends InstallWizardPage implements IInstallSummaryProvider, IInstallConsoleProvider, IInstallRepositoryListener { /** Component name column */ private static final int COLUMN_NAME = 0; /** Component version column */ private static final int COLUMN_VERSION = 1; /** Margin around components area */ private static final int COMPONENTS_MARGIN = 2; /** Indent of component description */ private static final int COMPONENT_DESCRIPTION_INDENT = 16; /** Component header height */ private static final int COMPONENT_HEADER_HEIGHT = 45; /** Message label */ protected Label messageLabel; /** Console list */ protected ConsoleListPrompter<IInstallComponent> consoleList; /** Expansion bar */ protected ExpandBar componentsBar; /** Required components expansion item */ protected ExpandItem requiredList; /** Required components panel */ protected ComponentsPanel requiredComponentsPanel; /** Optional components expansion item */ protected ExpandItem optionalList; /** Optional components panel */ protected ComponentsPanel optionalComponentsPanel; /** Title font */ protected Font titleFont; /** Dimmed color #1 */ protected Color dimColor1; /** Dimmed color #2 */ protected Color dimColor2; /** Button area */ protected Composite buttonArea; /** Select all button */ protected Button selectAllButton; /** Deselect all button */ protected Button deselectAllButton; /** Components scrolled container */ protected ScrolledComposite componentContainer; /** Label to display the install size */ protected Label installSizeLabel; /** Status area containing the install size label and progress bar */ protected Composite statusArea; /** Progress bar for the size calculation */ protected SpinnerProgress progressBar; /** Last calculated install size */ protected long installSize; /** Install description */ private IInstallDescription installDescription; /** Job to compute install plan */ private InstallPlanJob installPlanJob = new InstallPlanJob(); /** * Constructor * * @param pageName Page name * @param title Page title * @param installDescription Install description */ @SuppressWarnings("synthetic-access") public ComponentsPage(String pageName, String title, IInstallDescription installDescription) { super(pageName, title); this.installDescription = installDescription; } /** * Returns if components version should be displayed. * * @return <code>true</code> to display components version */ public boolean getHideComponentsVersion() { return installDescription.getHideComponentsVersion(); } @Override public void dispose() { RepositoryManager.getDefault().removeRepositoryListener(this); if (titleFont != null) { titleFont.dispose(); } if (dimColor1 != null) { dimColor1.dispose(); } if (dimColor2 != null) { dimColor2.dispose(); } super.dispose(); } /** * Returns the title font. * * @return Title font */ private Font getTitleFont() { return titleFont; } /** * Returns the first dimmed color. * * @return Dimmed color */ private Color getDimColor1() { return dimColor1; } /** * Returns the second dimmed color. * * @return Dimmed color */ private Color getDimColor2() { return dimColor2; } @SuppressWarnings("synthetic-access") @Override public Control createContents(Composite parent) { Composite area = new Composite(parent, SWT.NONE); GridLayout areaLayout = new GridLayout(); areaLayout.verticalSpacing = 0; area.setLayout(areaLayout); area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); // Create bold font FontData[] fd = getFont().getFontData(); fd[0].setStyle(SWT.BOLD); titleFont = new Font(getShell().getDisplay(), fd[0]); // Create dimmed colors RGB dimRGB = blendRGB(getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND).getRGB(), getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), 45); dimColor1 = new Color(getShell().getDisplay(), dimRGB); dimRGB = blendRGB(getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(), getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), 75); dimColor2 = new Color(getShell().getDisplay(), dimRGB); // Message label messageLabel = new Label(area, SWT.WRAP); messageLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 1, 1)); // Scrolled composite container componentContainer = new ScrolledComposite(area, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); componentContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); componentContainer.setExpandHorizontal(true); componentContainer.setExpandVertical(true); // Create the components bar componentsBar = new ExpandBar(componentContainer, SWT.NONE); componentsBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); componentsBar.setSpacing(COMPONENTS_MARGIN); componentsBar.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); componentsBar.setBackgroundMode(SWT.INHERIT_DEFAULT); componentContainer.setContent(componentsBar); // Create required components section requiredList = new ExpandItem(componentsBar, SWT.NONE); requiredList.setText(InstallMessages.ComponentsPage_Required); requiredList.setImage(Installer.getDefault().getImageRegistry().get(IInstallerImages.COMPONENT)); // Create required components panel requiredComponentsPanel = new ComponentsPanel(componentsBar); requiredList.setControl(requiredComponentsPanel); // Create optional components section optionalList = new ExpandItem(componentsBar, SWT.NONE); optionalList.setText(InstallMessages.ComponentsPage_Optional); optionalList.setImage(Installer.getDefault().getImageRegistry().get(IInstallerImages.COMPONENT_OPTIONAL)); // Create optional components panel optionalComponentsPanel = new ComponentsPanel(componentsBar); optionalList.setControl(optionalComponentsPanel); optionalComponentsPanel.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); for (IInstallComponent component : components) { if (component.isOptional()) { component.setInstall(false); Iterator<?> iter = selection.iterator(); while (iter.hasNext()) { if (component.equals(iter.next())) { component.setInstall(true); break; } } } } // Update install space for new component selection updateInstallPlan(); // Update button state updateButtons(); // Validate selection validate(); } }); // Button area buttonArea = new Composite(area, SWT.NONE); buttonArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); buttonArea.setLayout(new GridLayout(2, false)); // Select all optional button selectAllButton = new Button(buttonArea, SWT.PUSH); selectAllButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1)); selectAllButton.setText(InstallMessages.ComponentsPage_SelectAllOptional); selectAllButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectAllOptional(true); } }); // Deselect all optional button deselectAllButton = new Button(buttonArea, SWT.PUSH); deselectAllButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1)); deselectAllButton.setText(InstallMessages.ComponentsPage_DeselectAllOptional); deselectAllButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectAllOptional(false); } }); statusArea = new Composite(area, SWT.NONE); GridLayout gl = new GridLayout(1, false); gl.horizontalSpacing = 0; gl.verticalSpacing = 0; gl.marginHeight = 0; gl.marginWidth = 0; statusArea.setLayout(gl); statusArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); progressBar = new SpinnerProgress(statusArea, SWT.NONE); progressBar.setText(InstallMessages.ComponentsPage_ComputingSize); progressBar.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false, 1, 1)); installSizeLabel = new Label(statusArea, SWT.NONE); installSizeLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false, 1, 1)); setProgressVisible(false); // Listen to component changes RepositoryManager.getDefault().addRepositoryListener(this); // Update page updatePage(); return area; } /** * Selects/deselects all optional components. * * @param select <code>true</code> to select all, <code>false</code> to * deselect all */ private void selectAllOptional(boolean select) { if (optionalList != null) { ComponentsPanel panel = (ComponentsPanel) optionalList.getControl(); // Select all if (select) { panel.setSelection(new StructuredSelection(panel.getComponents())); } // Deselect all else { panel.setSelection(new StructuredSelection(new IInstallComponent[0])); } } } /** * Returns the components title. * * @return Title text */ private String getComponentsTitle() { return Installer.getDefault().getInstallManager().getInstallMode().isUpdate() ? InstallMessages.ComponentsPage_ComponentsLabelUpdate : InstallMessages.ComponentsPage_ComponentsLabelInstall; } @Override public void setVisible(boolean visible) { super.setVisible(visible); // Update page in case component attributes changed if (visible && !RepositoryManager.getDefault().isLoading()) { updatePage(); } } /** * Updates the page. */ private void updatePage() { // Width int minWidth = 0; // Height int minHeight = 0; // Components have been loaded if (!RepositoryManager.getDefault().isLoading()) { hideBusy(); setPageComplete(true); messageLabel.setText(getComponentsTitle()); // Add required and optional components IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); ArrayList<IInstallComponent> requiredComponents = new ArrayList<IInstallComponent>(); ArrayList<IInstallComponent> optionalComponents = new ArrayList<IInstallComponent>(); for (IInstallComponent component : components) { // Component is included if (component.isIncluded()) { if (component.isOptional()) { optionalComponents.add(component); } else { requiredComponents.add(component); } } } // Required components requiredComponentsPanel.setComponents( requiredComponents.toArray(new IInstallComponent[requiredComponents.size()]), false, getHideComponentsVersion()); Point requiredSize = requiredComponentsPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT); requiredList.setHeight(requiredSize.y); minWidth = requiredSize.x; // Expand the section requiredList.setExpanded(true); // Optional components optionalComponentsPanel.setComponents( optionalComponents.toArray(new IInstallComponent[optionalComponents.size()]), true, getHideComponentsVersion()); Point optionalSize = optionalComponentsPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT); optionalList.setHeight(optionalSize.y); if (optionalSize.x > minWidth) minWidth = optionalSize.x; // Expand the section optionalList.setExpanded(true); // Layout the components bar parent before computing sizes componentsBar.getParent().layout(true); // Compute minimum height to display all items // Note: Do not compute the size of componentsBar for minimum height. // Although, this works on Windows, it returns incorrect value on // GTK. // It is possible for ExpandBar.getHeaderHeight() to return // a negative value. minHeight = requiredSize.y + COMPONENT_HEADER_HEIGHT + componentsBar.getSpacing() + optionalSize.y + COMPONENT_HEADER_HEIGHT + componentsBar.getSpacing(); updateInstallPlan(); // Update buttons updateButtons(); } // Components not yet loaded else { setPageComplete(false); showBusy(InstallMessages.ComponentsPage_LoadingInstallInformation); } // Update the scrolled container size componentContainer.setMinHeight(minHeight); componentContainer.setMinWidth(minWidth); } /** * Sets the visibility of the progress bar. * @param visible */ private void setProgressVisible(final boolean visible) { getShell().getDisplay().syncExec(new Runnable() { @Override public void run() { progressBar.setVisible(visible); progressBar.setProgress(visible); int dimensionsProgress = (visible) ? SWT.DEFAULT : 0; int dimensionsLabel = (visible) ? 0 : SWT.DEFAULT; ((GridData) progressBar.getLayoutData()).widthHint = dimensionsProgress; ((GridData) progressBar.getLayoutData()).heightHint = dimensionsProgress; installSizeLabel.setVisible(!visible); ((GridData) installSizeLabel.getLayoutData()).widthHint = dimensionsLabel; ((GridData) installSizeLabel.getLayoutData()).heightHint = dimensionsLabel; statusArea.layout(true); } }); } /** * Updates the install plan. */ private void updateInstallPlan() { // Cancel current job if running if (installPlanJob.getState() != Job.NONE) { installPlanJob.cancel(); } // Schedule plan job installPlanJob.schedule(); } /** * Sets the install size label. * @param text */ private void setStatusText(final String text) { getShell().getDisplay().syncExec(new Runnable() { @Override public void run() { installSizeLabel.setText(text); statusArea.layout(true); } }); } /** * Updates the enabled/disable state of buttons. */ private void updateButtons() { if (optionalList != null) { buttonArea.setEnabled(true); boolean allSelected = true; boolean oneSelected = false; IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); for (IInstallComponent component : components) { if (component.isOptional()) { if (component.getInstall()) { oneSelected = true; } else { allSelected = false; } } } selectAllButton.setEnabled(!allSelected); deselectAllButton.setEnabled(oneSelected); } else { selectAllButton.setEnabled(false); deselectAllButton.setEnabled(false); } } /** * Component label provider */ private class ComponentLabelProvider extends LabelProvider implements ITableLabelProvider { @Override public Image getImage(Object element) { return getColumnImage(element, 0); } @Override public String getText(Object element) { return getColumnText(element, 0); } @Override public Image getColumnImage(Object element, int columnIndex) { Image image = null; if (element instanceof IInstallComponent) { IInstallComponent component = (IInstallComponent) element; if (columnIndex == 0) { // Add-on component String addon = (String) component.getProperty(IInstallComponent.PROPERTY_ADDON); if (Boolean.TRUE.toString().equals(addon)) { image = null; } // Optional component else if (component.isOptional()) { image = null; } // Required component else { image = null; } } } return image; } @Override public String getColumnText(Object element, int columnIndex) { String text = null; if (element instanceof IInstallComponent) { IInstallComponent component = (IInstallComponent) element; // Name column if (columnIndex == COLUMN_NAME) { text = component.getName(); } // Version column else if (columnIndex == COLUMN_VERSION) { text = component.getInstallUnit().getVersion().toString(); } } return text; } } @Override public String getInstallSummary() { StringBuffer buffer = new StringBuffer(); ArrayList<IInstallableUnit> toAdd = new ArrayList<IInstallableUnit>(); ArrayList<IInstallableUnit> toRemove = new ArrayList<IInstallableUnit>(); RepositoryManager.getDefault().getInstallUnits(toAdd, toRemove); // Added components ArrayList<IInstallComponent> addedComponents = new ArrayList<IInstallComponent>(); // Removed components ArrayList<IInstallComponent> removedComponents = new ArrayList<IInstallComponent>(); IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); for (IInstallComponent component : components) { if (toAdd.contains(component.getInstallUnit())) { addedComponents.add(component); } else if (toRemove.contains(component.getInstallUnit())) { removedComponents.add(component); } } // If an existing installation is being updated (otherwise it is a new // install or upgrade). boolean update = Installer.getDefault().getInstallManager().getInstallMode().isUpdate(); // Added components summary if (addedComponents.size() > 0) { buffer.append(update ? InstallMessages.ComponentsPage_Added : InstallMessages.ComponentsPage_Installed); for (IInstallComponent component : addedComponents) { buffer.append("\n\t"); buffer.append(component.getName()); if (!getHideComponentsVersion()) { buffer.append(" ("); buffer.append(component.getInstallUnit().getVersion().toString()); buffer.append(')'); } } } // Removed components summary if (removedComponents.size() > 0) { if (buffer.length() > 0) { buffer.append('\n'); } buffer.append( update ? InstallMessages.ComponentsPage_Removed : InstallMessages.ComponentsPage_NotInstalled); for (IInstallComponent component : removedComponents) { buffer.append("\n\t"); buffer.append(component.getName()); if (!getHideComponentsVersion()) { buffer.append(" ("); buffer.append(component.getInstallUnit().getVersion().toString()); buffer.append(')'); } } } if (buffer.length() > 0) { buffer.append("\n\n"); } return buffer.toString(); } @Override public void saveInstallData(IInstallData data) { // Save install size data.setProperty(IInstallConstants.PROPERTY_INSTALL_SIZE, installSize); } @Override public String getConsoleResponse(String input) throws IllegalArgumentException { String response = null; // Initial response if (input == null) { // Wait for the load RepositoryManager.getDefault().waitForLoad(); // Create console items list ComponentLabelProvider labelProvider = new ComponentLabelProvider(); consoleList = new ConsoleListPrompter<IInstallComponent>(getComponentsTitle()); IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); // Sort components by name Arrays.sort(components, new Comparator<IInstallComponent>() { @Override public int compare(IInstallComponent arg0, IInstallComponent arg1) { return arg0.getName().compareTo(arg1.getName()); } }); // Add components for (IInstallComponent component : components) { consoleList.addItem( labelProvider.getColumnText(component, COLUMN_NAME) + " - " //$NON-NLS-1$ + labelProvider.getColumnText(component, COLUMN_VERSION), component, component.getInstall(), component.isOptional()); } } // Get response response = consoleList.getConsoleResponse(input); // Set selected roots if (response == null) { ArrayList<IInstallComponent> selectedComponents = new ArrayList<IInstallComponent>(); consoleList.getSelectedData(selectedComponents); IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); for (IInstallComponent component : components) { if (component.isOptional()) { component.setInstall(false); for (IInstallComponent selectedComponent : selectedComponents) { if (component.equals(selectedComponent)) { component.setInstall(true); break; } } } } // Compute plan final IInstallPlan plan = RepositoryManager.getDefault().computeInstallPlan(null); // Error in install plan if ((plan != null) && (plan.getStatus().getSeverity() == IStatus.ERROR)) { response = MessageFormat.format("ERROR: {0}\n{1}", plan.getErrorMessage(), consoleList.toString()); } // Validate selections else { String status = getSelectionMessage(); // Selection error if (status != null) { response = MessageFormat.format("ERROR: {0}\n{1}", //$NON-NLS-1$ status, consoleList.toString()); } } } return response; } /** * Blends c1 and c2 based in the provided ratio. * * @param c1 * first color * @param c2 * second color * @param ratio * percentage of the first color in the blend (0-100) * @return the RGB value of the blended color * * copied from FormColors.java */ public RGB blendRGB(RGB c1, RGB c2, int ratio) { int r = blend(c1.red, c2.red, ratio); int g = blend(c1.green, c2.green, ratio); int b = blend(c1.blue, c2.blue, ratio); return new RGB(r, g, b); } /** * Blends two color values * * @param v1 First color value * @param v2 Second color value * @param ratio Ratio * @return Blended color value */ private int blend(int v1, int v2, int ratio) { int b = (ratio * v1 + (100 - ratio) * v2) / 100; return Math.min(255, b); } /** * Returns the status message for any selection error. * * @return Status message or <code>null</code> if no error */ private String getSelectionMessage() { String message = null; IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(); for (IInstallComponent component : components) { if (component.getInstall()) { IInstallComponent[] requiredComponents = component.getRequiredComponents(); if (requiredComponents != null) { for (IInstallComponent requiredComponent : requiredComponents) { if (!requiredComponent.getInstall()) { message = MessageFormat.format("{0} requires {1}.", //$NON-NLS-1$ component.getName(), requiredComponent.getName()); break; } } } } } return message; } @Override public boolean validate() { String message = getSelectionMessage(); // Show status for problems in selection if (message != null) { IStatus status = new Status(IStatus.ERROR, Installer.ID, message); showStatus(new IStatus[] { status }); } // Hide status if no problems else { hideStatus(); } setPageComplete(message == null); return (message == null); } @Override public void repositoryStatus(final RepositoryStatus status) { getShell().getDisplay().syncExec(new Runnable() { @Override public void run() { // Repositories loading if (status == IInstallRepositoryListener.RepositoryStatus.loadingStarted) { showBusy(InstallMessages.ComponentsPage_LoadingInstallInformation); setPageComplete(false); } // Repositories loaded else if (status == IInstallRepositoryListener.RepositoryStatus.loadingCompleted) { hideBusy(); updatePage(); validate(); } } }); } @Override public void repositoryLoaded(URI location, IInstallComponent[] components) { } @Override public void repositoryError(URI location, String errorMessage) { } /** * A panel that displays the name, version, and description for list of * components. */ private class ComponentsPanel extends Composite implements ISelectionProvider { /** Components for panel */ private IInstallComponent[] components; /** Selection listeners */ private ListenerList selectionListeners = new ListenerList(); /** Items */ private ArrayList<Composite> items = new ArrayList<Composite>(); /** Title buttons */ private ArrayList<Button> titleButtons = new ArrayList<Button>(); /** * Constructor * * @param parent Parent */ public ComponentsPanel(Composite parent) { super(parent, SWT.NONE); // Set colors Display display = getShell().getDisplay(); setBackground(display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND)); // Layout GridLayout layout = new GridLayout(1, false); layout.marginHeight = 2; layout.marginWidth = 2; layout.verticalSpacing = 0; setLayout(layout); } /** * Sets the components for the panel. * * @param components Components * @param optional <code>true</code> if components are optional */ public void setComponents(IInstallComponent[] components, boolean optional, boolean hideVersion) { this.components = components; for (Composite item : items) { item.dispose(); } items.clear(); titleButtons.clear(); ComponentLabelProvider labelProvider = new ComponentLabelProvider(); // Create items for each component for (IInstallComponent component : components) { // Component item area // |-name-|-version| // |--description--| Composite itemArea = new Composite(this, SWT.NONE); itemArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); GridLayout itemLayout = new GridLayout(1, false); itemLayout.marginWidth = 0; itemLayout.marginHeight = 2; itemLayout.verticalSpacing = 0; itemArea.setLayout(itemLayout); itemArea.setBackground(getBackground()); items.add(itemArea); // Title area Composite titleArea = new Composite(itemArea, SWT.NONE); GridLayout titleLayout = new GridLayout(3, false); titleLayout.marginWidth = 0; titleLayout.marginHeight = 0; titleArea.setLayout(titleLayout); titleArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); titleArea.setBackground(getBackground()); Label icon = new Label(titleArea, SWT.NONE); icon.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1)); icon.setImage(labelProvider.getImage(component)); String componentName = labelProvider.getColumnText(component, COLUMN_NAME); // If the components is optional, create a check-box so // it can be selected/unselected. if (optional) { final Button titleButton = new Button(titleArea, SWT.CHECK); titleButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); titleButton.setText(componentName); titleButton.setFont(getTitleFont()); titleButton.setSelection(component.getInstall()); titleButton.setData(component); titleButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Update listeners fireSelectionChanged(); } }); titleButton.setBackground(getBackground()); titleButtons.add(titleButton); } // Required component else { Label titleLabel = new Label(titleArea, SWT.NONE); titleLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); titleLabel.setText(componentName); titleLabel.setFont(getTitleFont()); titleLabel.setBackground(getBackground()); titleLabel.setForeground(getForeground()); } // Component version if (!hideVersion) { Label versionLabel = new Label(titleArea, SWT.NONE); versionLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 1, 1)); versionLabel.setText(component.getInstallUnit().getVersion().toString()); versionLabel.setForeground(getDimColor2()); versionLabel.setBackground(getBackground()); } // Component description String description = component.getDescription(); if (description != null) { Text descriptionText = new Text(itemArea, SWT.MULTI | SWT.WRAP); descriptionText.setEditable(false); GridData descriptionData = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); descriptionData.horizontalIndent = COMPONENT_DESCRIPTION_INDENT; descriptionText.setLayoutData(descriptionData); descriptionText.setText(description); descriptionText.setForeground(getDimColor1()); descriptionText.setBackground(getBackground()); } } layout(true); } /** * Fires a selection changed event to all listeners. */ private void fireSelectionChanged() { Object[] listeners = selectionListeners.getListeners(); SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection()); for (Object listener : listeners) { try { ((ISelectionChangedListener) listener).selectionChanged(event); } catch (Exception e) { e.printStackTrace(); } } } /** * Returns the components. * * @return Components */ public IInstallComponent[] getComponents() { return components; } @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { selectionListeners.add(listener); } @Override public ISelection getSelection() { ArrayList<IInstallComponent> items = new ArrayList<IInstallComponent>(); for (Button titleButton : titleButtons) { if (titleButton.getSelection()) { items.add((IInstallComponent) titleButton.getData()); } } return new StructuredSelection(items.toArray(new IInstallComponent[items.size()])); } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { selectionListeners.remove(listener); } @Override public void setSelection(ISelection selection) { if (selection instanceof IStructuredSelection) { for (Button titleButton : titleButtons) { IInstallComponent buttonComponent = (IInstallComponent) titleButton.getData(); boolean selected = false; Iterator<?> iter = ((IStructuredSelection) selection).iterator(); while (iter.hasNext()) { IInstallComponent selectedComponent = (IInstallComponent) iter.next(); if (buttonComponent.equals(selectedComponent)) { selected = true; break; } } titleButton.setSelection(selected); } fireSelectionChanged(); } } } @Override public boolean isSupported() { IInstallMode mode = Installer.getDefault().getInstallManager().getInstallMode(); return mode.isInstall(); } /** * A job to compute the install plan. */ private class InstallPlanJob extends Job { /** * Constructor */ public InstallPlanJob() { super("InstallPlanJob"); setSystem(true); } @Override protected IStatus run(IProgressMonitor monitor) { // Show progress getShell().getDisplay().syncExec(new Runnable() { @Override public void run() { setProgressVisible(true); } }); // Compute plan final IInstallPlan plan = RepositoryManager.getDefault().computeInstallPlan(monitor); // Hide progress and update install plan size and status if ((plan != null) && !(getShell() == null) && !getShell().isDisposed()) { getShell().getDisplay().syncExec(new Runnable() { @Override public void run() { // Update size information setProgressVisible(false); ComponentsPage.this.installSize = plan.getSize(); String msg = MessageFormat.format(InstallMessages.ComponentsPage_0, UIUtils.formatBytes(installSize)); setStatusText(msg); // Update plan status if (plan.getStatus().isOK()) { hideStatus(); } else { String errorMessage = plan.getErrorMessage(); if (errorMessage != null) { showStatus( new IStatus[] { new Status(IStatus.WARNING, Installer.ID, errorMessage) }); } } } }); } return Status.OK_STATUS; } } }