/******************************************************************************* * 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.util.ArrayList; import java.util.Collection; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.ILicense; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; 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.Composite; import org.eclipse.swt.widgets.Control; import com.codesourcery.installer.IInstallComponent; import com.codesourcery.installer.IInstallConsoleProvider; import com.codesourcery.installer.IInstallData; import com.codesourcery.installer.IInstallMode; import com.codesourcery.installer.Installer; import com.codesourcery.installer.LicenseDescriptor; import com.codesourcery.installer.console.ConsoleYesNoPrompter; import com.codesourcery.installer.ui.IInstallPages; import com.codesourcery.internal.installer.InstallMessages; import com.codesourcery.internal.installer.RepositoryManager; /** * Page to show license agreement. * This page supports console. */ public class LicensePage extends InformationPage implements IInstallConsoleProvider { /** Available licenses */ private LicenseDescriptor[] availableLicenses; /** Fixed licenses */ private LicenseDescriptor[] licenses; /** License list */ private TableViewer list; /** Accept licenses button */ private Button acceptLicenseButton; /** Last license count */ private int lastLicenseCount = 0; /** Main area */ private Composite mainArea; /** Sash dividing license list from license information */ private SashForm sash; /** License information control */ private Control licenseInformationControl; /** Members used for retaining selection. */ private LicenseDescriptor firstLicense; private IStructuredSelection lastLicenseSelection = StructuredSelection.EMPTY; /** * Constructor * * @param licenses Array of licenses or <code>null</code> */ public LicensePage(LicenseDescriptor[] licenses) { super (IInstallPages.LICENSE_PAGE, InstallMessages.LicensePageTitle, ""); this.licenses = licenses; setInformationTitle(InstallMessages.LicenseMessageMultipleLicenses); // Enable scrolling setScrollable(true); // Set incomplete until license is accepted setPageComplete(false); } /** * Returns the licenses. * * @return Licenses or <code>null</code> */ public LicenseDescriptor[] getLicenses() { return licenses; } /** * Returns available licenses. This will include any licenses from files and any licenses from installable units * for selected components. * * @return Available licenses or <code>null</code> */ protected LicenseDescriptor[] getAvailableLicenses() { return availableLicenses; } /** * Sets available licenses. * * @param availableLicenses All licenses or <code>null</code> */ protected void setAvailableLicenses(LicenseDescriptor[] availableLicenses) { this.availableLicenses = availableLicenses; } @Override public Control createInformationArea(Composite parent) { // Main area mainArea = new Composite(parent, SWT.NONE); mainArea.setLayoutData(new GridData(GridData.FILL_BOTH)); mainArea.setLayout(new GridLayout()); // Sash between license list and license information sash = new SashForm(mainArea, SWT.HORIZONTAL); sash.setLayoutData(new GridData(GridData.FILL_BOTH)); // License area Composite area = new Composite(sash, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginHeight = layout.marginWidth = 0; area.setLayout(layout); // License list viewer list = new TableViewer(area, SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); list.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); list.setContentProvider(ArrayContentProvider.getInstance()); // Enable tool-tips for viewer ColumnViewerToolTipSupport.enableFor(list); // License list label provider list.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { LicenseDescriptor descriptor = (LicenseDescriptor) element; return descriptor.getLicenseName(); } @Override public String getToolTipText(Object element) { LicenseDescriptor descriptor = (LicenseDescriptor) element; return descriptor.getLicenseName(); } }); // Update license information on license selection changed list.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { lastLicenseSelection = (IStructuredSelection) event.getSelection(); if(lastLicenseSelection.isEmpty()) return; LicenseDescriptor ld = (LicenseDescriptor) lastLicenseSelection.getFirstElement(); setInformation(ld.getLicenseText() == null ? "" : ld.getLicenseText()); } }); // Create license information area licenseInformationControl = super.createInformationArea(sash); // Set license information area to occupy 2/3 of available horizontal space by default sash.setWeights(new int[] { 1, 3 }); // License accept button Composite acceptComp = new Composite(mainArea, SWT.NONE); layout = new GridLayout(); layout.marginWidth = 0; acceptComp.setLayout(layout); acceptComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); createAcceptButton(acceptComp); return area; } /** * Returns the main area composite. * * @return Main area */ private Composite getMainArea() { return mainArea; } /** * Returns the sash form containing the license list and license information. * * @return Sash form */ private SashForm getSash() { return sash; } /** * Create accept button * @param parent Parent control * @return Accept button */ protected Control createAcceptButton(Composite parent) { acceptLicenseButton = new Button(parent, SWT.CHECK); acceptLicenseButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); acceptLicenseButton.setText(InstallMessages.AcceptLicenses); acceptLicenseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setPageComplete(acceptLicenseButton.getSelection()); } }); return parent; } @Override public String getConsoleResponse(String input) throws IllegalArgumentException { String message = InstallMessages.LicensePageConsoleMessage + "\n\n" + getConsoleLicenseAgreements(); ConsoleYesNoPrompter prompter = new ConsoleYesNoPrompter(message, InstallMessages.LicensePageConsolePrompt); String response = prompter.getConsoleResponse(input); if ((response == null) && !prompter.getResult()) { throw new IllegalArgumentException(InstallMessages.LicensePageLicenseNotAccepted); } return response; } /** * Updates the licenses */ private void updateLicenses() { ArrayList<LicenseDescriptor> licenses = new ArrayList<LicenseDescriptor>(); if ((getLicenses() != null) && (getLicenses().length > 0)) { // Process the license descriptors for (LicenseDescriptor license : getLicenses()) { // License from text file if (license.getUnit() == null) { if ((license.getLicenseText() != null) && !license.getLicenseText().isEmpty()) { licenses.add(license); } } // License for installable unit else { IInstallComponent[] components = RepositoryManager.getDefault().getInstallComponents(false); for (IInstallComponent component : components) { // Component included in install if (component.getInstall()) { IInstallableUnit unit = component.getInstallUnit(); if (unit != null) { if (unit.getId().equals(license.getUnit().getId())) { try { // Add the unit licenses Collection<ILicense> iuLicenses = unit.getLicenses(null); for (ILicense iuLicense : iuLicenses) { LicenseDescriptor licenseDesc = new LicenseDescriptor(iuLicense.getBody(), (license.getLicenseName() != null) ? license.getLicenseName() : unit.getProperty(IInstallableUnit.PROP_NAME, null)); licenses.add(licenseDesc); } } catch (Exception e) { Installer.log(e); } break; } } } } } } } // Set all licenses setAvailableLicenses(licenses.toArray(new LicenseDescriptor[licenses.size()])); if (!isConsoleMode()) { if (!licenses.isEmpty()) firstLicense = licenses.get(0); list.setInput(getAvailableLicenses()); } } @Override public void setVisible(boolean visible) { // Update licenses updateLicenses(); // No licenses if (getAvailableLicenses().length == 0) { setInformationTitle(InstallMessages.LicensePageNoComponents); showStatus(new IStatus[] { new Status(IStatus.OK, Installer.ID, InstallMessages.ClickNext) }); getMainArea().setVisible(false); setPageComplete(true); } // Licenses else { hideStatus(); getMainArea().setVisible(true); setPageComplete(acceptLicenseButton.getSelection()); list.setSelection(lastLicenseSelection); IStructuredSelection ns = (IStructuredSelection) list.getSelection(); if(ns.isEmpty() && firstLicense != null) list.setSelection(new StructuredSelection(firstLicense)); int currentLicenseCount = list.getTable().getItemCount(); // Check if Item count has been changed if (currentLicenseCount != lastLicenseCount) { // Single license if ( currentLicenseCount == 1) { acceptLicenseButton.setText(InstallMessages.AcceptLicense); setInformationTitle(InstallMessages.LicenseMessageSingleLicense); // Hide license list getSash().setMaximizedControl(licenseInformationControl); } // Multiple licenses else { acceptLicenseButton.setText(InstallMessages.AcceptLicenses); setInformationTitle(InstallMessages.LicenseMessageMultipleLicenses); // Show license list getSash().setMaximizedControl(null); } // Update License count lastLicenseCount = currentLicenseCount; } } super.setVisible(visible); } @Override public void setActive(IInstallData data) { super.setActive(data); // Update licenses for console mode updateLicenses(); } /** * Get list of license agreements to show for head-less installer. Licenses are listed in following way: * License Name: Name of License * Text of License agreement * * @return Formated string containing license agreement(s) */ private String getConsoleLicenseAgreements() { StringBuffer licenseInfo = new StringBuffer(); for (LicenseDescriptor license : getAvailableLicenses()) { String licenseText = NLS.bind(InstallMessages.LicensePageLicenseName1, license.getLicenseName(), license.getLicenseText()); licenseInfo.append(licenseText); } return licenseInfo.toString(); } @Override public boolean isSupported() { IInstallMode mode = Installer.getDefault().getInstallManager().getInstallMode(); return mode.isInstall(); } }