/******************************************************************************* * Copyright (c) 2015 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.util.ArrayList; import java.util.HashMap; import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; 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.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import com.codesourcery.installer.IInstallConsoleProvider; import com.codesourcery.installer.IInstallData; import com.codesourcery.installer.IInstalledProduct; import com.codesourcery.installer.Installer; import com.codesourcery.installer.console.ConsoleListPrompter; import com.codesourcery.installer.ui.FormattedLabel; import com.codesourcery.installer.ui.InfoButton; import com.codesourcery.installer.ui.InfoList; import com.codesourcery.internal.installer.InstallMessages; import com.codesourcery.internal.installer.ui.InstallWizardDialog; /** * Abstract page for setup options. Subclasses should provide {@link #createOptions()} * to create the options for selection. */ public abstract class AbstractListSetupPage extends AbstractSetupPage implements IInstallConsoleProvider { /** Title font */ private Font titleFont; /** Currently selection */ private Option selection; /** Console list prompter */ private ConsoleListPrompter<Option> consoleList; /** Options list */ private InfoList optionsList; /** Title message */ private String titleMessage; /** Prompt message */ private String prompt; /** <code>true</code> to draw border around options */ private boolean border = false; /** Options */ private ArrayList<Option> options = new ArrayList<Option>(); /** Option buttons */ private HashMap<Option, InfoButton> buttons = new HashMap<Option, InfoButton>(); /** * Constructor * * @param pageName Page name * @param titleMessage or <code>null</code> * @param prompt or <code>null</code> */ protected AbstractListSetupPage(String pageName, String titleMessage, String prompt) { super(pageName, ""); this.titleMessage = titleMessage; this.prompt = prompt; setPageComplete(false); } /** * This method is called to create all options. * Subclasses should call {@link #addOption(Option)} to add a new option. */ protected abstract void createOptions(); /** * This method is called to save the selected option. * * @param selectedOption Selected option * @throws CoreException on failure */ protected abstract void saveOption(Option selectedOption) throws CoreException; /** * Sets a border around the options area. * * @param border <code>true</code> to border */ protected void setBorder(boolean border) { this.border = border; } /** * Returns if there is a border around the options area. * * @return <code>true</code> if border */ protected boolean getBorder() { return border; } /** * Returns the title message. * * @return Title message or <code>null</code> */ protected String getTitleMessage() { return titleMessage; } /** * Returns the prompt message. * * @return Prompt message or <code>null</code> */ protected String getPrompt() { return prompt; } @Override public void dispose() { if (titleFont != null) { titleFont.dispose(); titleFont = null; } super.dispose(); } /** * Returns the current selection. * * @return Selection or <code>null</code> */ protected Option getSelection() { return selection; } /** * Sets the current selection. * * @param selection Selection or <code>null</code> */ protected void setSelection(Option selection) { this.selection = selection; if (selection != null) { setPageComplete(true); } } @Override public Control createContents(Composite parent) { // Main area Composite area = new Composite(parent, SWT.NONE); area.setLayout(new GridLayout(1, true)); area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // Create title font FontData fontData = getFont().getFontData()[0]; fontData.setHeight(fontData.getHeight() + 2); titleFont = new Font(getShell().getDisplay(), fontData); // Title if (getTitleMessage() != null) { FormattedLabel titleLabel = new FormattedLabel(area, SWT.WRAP); titleLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); //titleLabel.setFont(titleFont); titleLabel.setText(getTitleMessage()); } // Spacing after title Label spacing = new Label(area, SWT.NONE); spacing.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); // Button area final Composite buttonArea = new Composite(area, SWT.NONE); GridLayout buttonLayout = new GridLayout(1, true); buttonLayout.verticalSpacing = 0; buttonArea.setLayout(buttonLayout); buttonArea.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, true)); // Prompt if (getPrompt() != null) { Label promptLabel = new Label(buttonArea, SWT.NONE); promptLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false)); promptLabel.setText(getPrompt()); promptLabel.setFont(getBoldFont()); } // Spacing after prompt spacing = new Label(buttonArea, SWT.NONE); spacing.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); // Create items area int listStyle = SWT.V_SCROLL; if (getBorder()) listStyle |= SWT.BORDER; optionsList = new InfoList(buttonArea, listStyle); optionsList.setShortenText(true); optionsList.setLabelFont(titleFont); optionsList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // Set option on selection optionsList.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { InfoButton button = (InfoButton)e.widget; setSelection((Option)button.getData()); } }); // Move to next page on double-click optionsList.addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(MouseEvent e) { ((InstallWizardDialog)getContainer()).nextPressed(); } }); // Create choices createOptions(); return area; } /** * Returns the options. * * @return Options */ protected Option[] getOptions() { return options.toArray(new Option[options.size()]); } /** * Adds an option. * * @param option Option to add */ protected void addOption(Option option) { // Add option options.add(option); if (!isConsoleMode()) { InfoButton item = optionsList.addItem(option.getImage(), option.getLabel(), option.getDescription()); item.setData(option); buttons.put(option, item); } } /** * Selects an option. * * @param option Option */ protected void selectOption(Option option) { if (buttons.containsKey(option)) { setSelection(option); buttons.get(option).setSelection(true); } } /** * Sets the existing product to use for install location. * * @param product Product * @throws CoreException on failure */ public void setProduct(final IInstalledProduct product) throws CoreException { final CoreException[] error = new CoreException[] { null }; if (isConsoleMode()) { printConsole(InstallMessages.PreparingInstall); try { Installer.getDefault().getInstallManager().setInstalledProduct(product, null); } catch (CoreException e) { error[0] = e; } } else { runOperation(InstallMessages.PreparingInstall, new Runnable() { @Override public void run() { try { Installer.getDefault().getInstallManager().setInstalledProduct(product, null); } catch (CoreException e) { error[0] = e; } } }); } if (error[0] != null) { Installer.log(error[0]); throw error[0]; } } @Override public String getConsoleResponse(String input) throws IllegalArgumentException { String response = null; // Initial prompt if (input == null) { consoleList = new ConsoleListPrompter<Option>(formatConsoleMessage(getTitleMessage()), true); // Add choices createOptions(); for (Option option : options) { StringBuffer itemName = new StringBuffer(); itemName.append(option.getLabel()); itemName.append(" ("); itemName.append(option.getDescription()); itemName.append(')'); consoleList.addItem(itemName.toString(), option); } } // Get response response = consoleList.getConsoleResponse(input); if (response == null) { ArrayList<Option> selection = new ArrayList<Option>(); consoleList.getSelectedData(selection); if (selection.size() > 0) { setSelection(selection.get(0)); } } return response; } @Override protected void saveSetup(IInstallData data) throws CoreException { Option selection = getSelection(); if (selection != null) { saveOption(selection); } } /** * Page option */ protected class Option { /** Option data */ private Object data; /** Option image */ private Image image; /** Option label */ private String label; /** Option description */ private String description; /** * Constructor * * @param data Option data * @param image Image or <code>null</code> * @param label Image label * @param description Image description or <code>null</code> */ public Option(Object data, Image image, String label, String description) { this.data = data; this.image = image; this.label = label; this.description = description; } /** * Returns the choice data. * * @return Data */ public Object getData() { return data; } /** * Returns the image. * * @return Identifier */ public Image getImage() { return image; } /** * Returns the label. * * @return Label */ public String getLabel() { return label; } /** * Returns the description. * * @return Description */ public String getDescription() { return description; } } }