blob: ff7d6cd668d7222881043bdb422946d0348aee18 [file] [log] [blame]
/*
* Copyright (c) 2015-2017 Eike Stepper (Loehne, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Eike Stepper - initial API and implementation
* Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
import org.eclipse.oomph.internal.setup.SetupProperties;
import org.eclipse.oomph.internal.ui.AccessUtil;
import org.eclipse.oomph.internal.ui.FlatButton;
import org.eclipse.oomph.internal.ui.ImageHoverButton;
import org.eclipse.oomph.internal.ui.ToggleSwitchButton;
import org.eclipse.oomph.p2.core.AgentManager;
import org.eclipse.oomph.p2.core.BundlePool;
import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.ProfileTransaction.Resolution;
import org.eclipse.oomph.p2.internal.ui.AgentManagerDialog;
import org.eclipse.oomph.setup.Index;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.ProductCatalog;
import org.eclipse.oomph.setup.ProductVersion;
import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.internal.core.util.CatalogManager;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
import org.eclipse.oomph.setup.internal.core.util.IndexManager;
import org.eclipse.oomph.setup.internal.installer.SimpleInstallerMenu.InstallerMenuItem;
import org.eclipse.oomph.setup.internal.installer.SimpleMessageOverlay.ControlRelocator;
import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.setup.ui.wizards.ConfigurationProcessor;
import org.eclipse.oomph.setup.ui.wizards.MarketPlaceListingProcessor;
import org.eclipse.oomph.setup.ui.wizards.ProjectPage;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.SelectionMemento;
import org.eclipse.oomph.ui.ErrorDialog;
import org.eclipse.oomph.ui.StatusDialog;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.ExceptionHandler;
import org.eclipse.oomph.util.IOExceptionWithCause;
import org.eclipse.oomph.util.OS;
import org.eclipse.oomph.util.OomphPlugin.BundleFile;
import org.eclipse.oomph.util.OomphPlugin.Preference;
import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.oomph.util.StringUtil;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
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.Label;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* @author Eike Stepper
*/
public final class SimpleInstallerDialog extends AbstractSimpleDialog implements InstallerUI
{
private static final String CATALOGS_MENU_ITEM_TEXT = ProductCatalogsDialog.TITLE.toUpperCase() + StringUtil.HORIZONTAL_ELLIPSIS;
private static final String APPLY_CONFIGURATION_MENU_ITEM_TEXT = "APPLY CONFIGURATION";
private static final String SWITCH_CATALOG_INDEX_MENU_ITEM_TEXT = "SWITCH CATALOG INDEX";
private static final String BUNDLE_POOLS_MENU_ITEM_TEXT = "BUNDLE POOLS" + StringUtil.HORIZONTAL_ELLIPSIS;
private static final String UPDATE_MENU_ITEM_TEXT = "UPDATE";
private static final String ADVANCED_MENU_ITEM_TEXT = "ADVANCED MODE" + StringUtil.HORIZONTAL_ELLIPSIS;
private static final String MARKET_PLACE_MENU_ITEM_TEXT = "MARKETPLACE" + StringUtil.HORIZONTAL_ELLIPSIS;
private static final String ABOUT_MENU_ITEM_TEXT = "ABOUT";
private static final String EXIT_MENU_ITEM_TEXT = "EXIT";
private static final Preference PREF_POOL_ENABLED = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("poolEnabled");
/**
* Adds the p2 bundle pool buttons to the UI if the bundle pool location isn't specified or isn't specified to be '@none'.
*/
private static final boolean SHOW_BUNDLE_POOL_UI = PropertiesUtil.getProperty(AgentManager.PROP_BUNDLE_POOL_LOCATION) == null
|| !AgentManager.BUNDLE_POOL_LOCATION_NONE.equalsIgnoreCase(PropertiesUtil.getProperty(AgentManager.PROP_BUNDLE_POOL_LOCATION));
private static final boolean MARKETPLACE_MENU_ITEM_ENABLED = !"false".equals(PropertiesUtil.getProperty(SetupProperties.PROP_SETUP_INSTALLER_MARKETPLACE));
private static Font defaultFont;
private static Point defaultSize;
private static String css;
private static String pageTemplate;
private static String productTemplate;
private static String productTemplateLarge;
private final Installer installer;
private final boolean restarted;
private final CatalogManager catalogManager;
private final PageStack pageStack = new PageStack();
private Composite stack;
private StackLayout stackLayout;
private SimpleProductPage productPage;
private SimpleVariablePage variablePage;
private SimpleReadmePage readmePage;
private SimpleInstallationLogPage installationLogPage;
private SimpleKeepInstallerPage keepInstallerPage;
private SimpleInstallerMenu installerMenu;
private SimpleInstallerMenuButton menuButton;
private boolean poolEnabled;
private BundlePool pool;
private Resolution updateResolution;
private SimpleMessageOverlay currentMessage;
private ToggleSwitchButton bundlePoolSwitch;
private boolean showProductCatalogsItem;
public SimpleInstallerDialog(Display display, Installer installer, boolean restarted)
{
super(display, OS.INSTANCE.isMac() ? SWT.TOOL : SWT.NO_TRIM, getDefaultSize(display).x, getDefaultSize(display).y);
setMinimumSize(385, 75);
this.installer = installer;
this.restarted = restarted;
catalogManager = installer.getCatalogManager();
}
protected void applyConfiguration()
{
MarketPlaceListingProcessor marketPlaceListingProcessor = new MarketPlaceListingProcessor(installer);
if (marketPlaceListingProcessor.isMarketPlaceListing())
{
marketPlaceListingProcessor.processMarketPlaceListing();
IStatus status = marketPlaceListingProcessor.getStatus();
if (!status.isOK())
{
new StatusDialog(getShell(), "Marketplace Listing Problems", null, status, Diagnostic.ERROR).open();
}
}
else
{
ConfigurationProcessor configurationProcessor = new ConfigurationProcessor(installer)
{
@Override
protected void handleSwitchToAdvancedMode()
{
switchToAdvancedMode();
}
@Override
protected boolean applyEmptyProductVersion()
{
applyInstallation();
return true;
}
@Override
protected boolean applyProductVersion(ProductVersion productVersion)
{
applyInstallation();
productPage.handleFilter("");
productPage.productSelected(productVersion.getProduct());
variablePage.setProductVersion(productVersion);
return true;
}
};
if (configurationProcessor.processWorkspace())
{
configurationProcessor.processInstallation();
}
IStatus status = configurationProcessor.getStatus();
if (!status.isOK())
{
new StatusDialog(getShell(), "Configuration Problems", null, status, Diagnostic.ERROR).open();
}
}
}
@Override
protected void createUI(Composite titleComposite)
{
Composite exitMenuButtonContainer = new Composite(titleComposite, SWT.NONE);
exitMenuButtonContainer.setLayout(UIUtil.createGridLayout(1));
exitMenuButtonContainer.setLayoutData(GridDataFactory.swtDefaults().grab(false, true).align(SWT.CENTER, SWT.FILL).create());
FlatButton exitButton = new ImageHoverButton(exitMenuButtonContainer, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit.png"),
SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit_hover.png"));
exitButton.setShowButtonDownState(false);
exitButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).create());
exitButton.setToolTipText("Exit");
exitButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
exitSelected();
}
});
menuButton = new SimpleInstallerMenuButton(exitMenuButtonContainer);
menuButton.setLayoutData(GridDataFactory.swtDefaults().grab(false, true).align(SWT.CENTER, SWT.BEGINNING).indent(11, 0).create());
menuButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
// Don't use the event, it can be null!
toggleMenu();
}
});
stackLayout = new StackLayout();
stack = new Composite(this, SWT.NONE);
stack.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
stack.setLayout(stackLayout);
SelectionMemento selectionMemento = installer.getSelectionMemento();
productPage = new SimpleProductPage(stack, this, selectionMemento);
variablePage = new SimpleVariablePage(stack, this, selectionMemento);
if (UIUtil.isBrowserAvailable())
{
readmePage = new SimpleReadmePage(stack, this);
}
installationLogPage = new SimpleInstallationLogPage(stack, this);
keepInstallerPage = new SimpleKeepInstallerPage(stack, this);
switchToPage(productPage);
Display display = getDisplay();
if (!restarted)
{
Thread updateSearcher = new UpdateSearcher(display);
updateSearcher.start();
}
display.timerExec(500, new Runnable()
{
public void run()
{
installer.getResourceSet().getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
installer.loadIndex();
}
});
// Initialize menu.
getInstallerMenu();
final PropertyChangeListener catalogManagerListener = new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
if (CatalogManager.PROPERTY_INDEX.equals(evt.getPropertyName()))
{
indexLoaded((Index)evt.getNewValue());
}
}
};
catalogManager.addPropertyChangeListener(catalogManagerListener);
addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
catalogManager.removePropertyChangeListener(catalogManagerListener);
}
});
enablePool(SHOW_BUNDLE_POOL_UI && PREF_POOL_ENABLED.get(true));
updateAvailable(false);
}
private void indexLoaded(Index index)
{
@SuppressWarnings("unchecked")
List<ProductCatalog> productCatalogs = (List<ProductCatalog>)catalogManager.getCatalogs(true);
int count = 0;
if (productCatalogs != null)
{
for (ProductCatalog productCatalog : productCatalogs)
{
if (SimpleProductPage.isIncluded(productCatalog))
{
++count;
}
}
}
// Show it if there is more than one catalog,
// or if there are no filters in place and there indices available to switch to.
// This will not show it for the crippled installer because it has filters in place.
showProductCatalogsItem = count > 1
|| StringUtil.isEmpty(SimpleInstallerPage.PRODUCT_CATALOG_FILTER.pattern()) && StringUtil.isEmpty(SimpleInstallerPage.PRODUCT_FILTER.pattern())
&& StringUtil.isEmpty(SimpleInstallerPage.PRODUCT_VERSION_FILTER.pattern()) && new IndexManager().getIndexNames(false).size() > 1;
}
private void toggleMenu()
{
SimpleInstallerMenu installerMenu = getInstallerMenu();
boolean show = !installerMenu.isVisible();
Installer installer = getInstaller();
if (show)
{
installer.setConfigurationResources(Collections.<Resource> emptySet());
SimpleInstallerPage topPage = getTopPage();
if (topPage != null)
{
topPage.menuAboutToShow(installerMenu);
}
InstallerMenuItem switchCatalogIndexItem = installerMenu.findMenuItemByName(SWITCH_CATALOG_INDEX_MENU_ITEM_TEXT);
InstallerMenuItem catalogsMenuItem = installerMenu.findMenuItemByName(CATALOGS_MENU_ITEM_TEXT);
InstallerMenuItem applyConfigurationMenuItem = installerMenu.findMenuItemByName(APPLY_CONFIGURATION_MENU_ITEM_TEXT);
if (topPage == productPage)
{
Collection<? extends Resource> configurationResources = installer.getUnappliedConfigurationResources();
URI indexLocation = ProjectPage.ConfigurationListener.getIndexURI(configurationResources);
applyConfigurationMenuItem.setVisible(!configurationResources.isEmpty() && indexLocation == null);
boolean switchCatalogVisible = indexLocation != null && !catalogManager.isCurrentIndex(indexLocation);
switchCatalogIndexItem.setVisible(switchCatalogVisible);
if (switchCatalogVisible)
{
switchCatalogIndexItem.setToolTipText("Switch to the catalog index from the clipboard: " + IndexManager.getUnderlyingLocation(indexLocation));
}
catalogsMenuItem.setVisible(showProductCatalogsItem);
}
else
{
catalogsMenuItem.setVisible(false);
applyConfigurationMenuItem.setVisible(false);
switchCatalogIndexItem.setVisible(false);
}
}
installerMenu.setVisible(show);
}
public Installer getInstaller()
{
return installer;
}
public void setButtonsEnabled(boolean enabled)
{
menuButton.setEnabled(enabled);
}
private void enablePool(boolean poolEnabled)
{
if (this.poolEnabled != poolEnabled)
{
this.poolEnabled = poolEnabled;
PREF_POOL_ENABLED.set(poolEnabled);
}
if (poolEnabled)
{
pool = P2Util.getAgentManager().getDefaultBundlePool(SetupUIPlugin.INSTANCE.getSymbolicName());
}
else
{
pool = null;
}
if (bundlePoolSwitch != null)
{
bundlePoolSwitch.setSelected(poolEnabled);
}
}
public BundlePool getPool()
{
return pool;
}
private SimpleInstallerMenu getInstallerMenu()
{
if (installerMenu == null)
{
installerMenu = createInstallerMenu();
}
return installerMenu;
}
private SimpleInstallerMenu createInstallerMenu()
{
final SimpleInstallerMenu menu = new SimpleInstallerMenu(this);
SimpleInstallerMenu.InstallerMenuItem updateInstallerItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
updateInstallerItem.setDefaultImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exclamation_circle.png"));
updateInstallerItem.setHoverImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exclamation_circle_hover.png"));
updateInstallerItem.setText(UPDATE_MENU_ITEM_TEXT);
updateInstallerItem.setToolTipText("Install available updates");
updateInstallerItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
Runnable successRunnable = new Runnable()
{
public void run()
{
restart();
}
};
ExceptionHandler<CoreException> exceptionHandler = new ExceptionHandler<CoreException>()
{
public void handleException(CoreException ex)
{
ErrorDialog.open(ex);
}
};
SelfUpdate.update(getShell(), updateResolution, successRunnable, exceptionHandler, null);
}
});
SimpleInstallerMenu.InstallerMenuItem applyConfigurationItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
applyConfigurationItem.setText(APPLY_CONFIGURATION_MENU_ITEM_TEXT);
applyConfigurationItem.setToolTipText("Apply the configuration from the clipboard");
applyConfigurationItem.setVisible(false);
applyConfigurationItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
applyConfiguration();
}
});
SimpleInstallerMenu.InstallerMenuItem switchCatalogIndexItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
switchCatalogIndexItem.setText(SWITCH_CATALOG_INDEX_MENU_ITEM_TEXT);
switchCatalogIndexItem.setVisible(false);
switchCatalogIndexItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
applyConfiguration();
}
});
SimpleInstallerMenu.InstallerMenuItem catalogsItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
catalogsItem.setText(CATALOGS_MENU_ITEM_TEXT);
catalogsItem.setToolTipText(ProductCatalogsDialog.DESCRIPTION);
catalogsItem.setVisible(false);
catalogsItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
ProductCatalogsDialog productCatalogsDialog = new ProductCatalogsDialog(SimpleInstallerDialog.this, getInstaller(), catalogManager);
productCatalogsDialog.open();
}
});
AccessUtil.setKey(catalogsItem, "catalogs");
// Label spacer1 = new Label(menu, SWT.NONE);
// spacer1.setLayoutData(GridDataFactory.swtDefaults().hint(SWT.DEFAULT, 46).create());
SimpleInstallerMenu.InstallerMenuItem advancedModeItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
advancedModeItem.setText(ADVANCED_MENU_ITEM_TEXT);
advancedModeItem.setToolTipText("Switch to advanced mode");
advancedModeItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
switchToAdvancedMode();
}
});
if (SHOW_BUNDLE_POOL_UI)
{
SimpleInstallerMenu.InstallerMenuItemWithToggle bundlePoolsItem = new SimpleInstallerMenu.InstallerMenuItemWithToggle(menu);
bundlePoolsItem.setText(BUNDLE_POOLS_MENU_ITEM_TEXT);
bundlePoolsItem.setToolTipText(AgentManagerDialog.MESSAGE);
// bundlePoolsItem.setDividerVisible(false);
bundlePoolsItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
manageBundlePools();
}
});
bundlePoolSwitch = bundlePoolsItem.getToggleSwitch();
bundlePoolSwitch.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
enablePool(bundlePoolSwitch.isSelected());
}
});
}
if (MARKETPLACE_MENU_ITEM_ENABLED)
{
SimpleInstallerMenu.InstallerMenuItem marketPlaceItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
marketPlaceItem.setText(MARKET_PLACE_MENU_ITEM_TEXT);
marketPlaceItem.setToolTipText("Browse for marketplace listings and drag them onto the installer's title");
marketPlaceItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
OS.INSTANCE.openSystemBrowser("https://marketplace.eclipse.org");
}
});
}
SimpleInstallerMenu.InstallerMenuItem aboutItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
aboutItem.setText(ABOUT_MENU_ITEM_TEXT);
aboutItem.setToolTipText("Show information about this installer");
aboutItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
showAbout();
}
});
SimpleInstallerMenu.InstallerMenuItem exitItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
exitItem.setText(EXIT_MENU_ITEM_TEXT);
exitItem.setDividerVisible(false);
exitItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
exitSelected();
}
});
return menu;
}
private void updateAvailable(boolean available)
{
menuButton.setNotificationVisible(available);
installerMenu.findMenuItemByName(UPDATE_MENU_ITEM_TEXT).setVisible(available);
installerMenu.layout();
}
private void manageBundlePools()
{
final boolean[] enabled = { poolEnabled };
AgentManagerDialog dialog = new AgentManagerDialog(getShell())
{
@Override
protected void createUI(Composite parent)
{
final Button enabledButton = new Button(parent, SWT.CHECK);
enabledButton.setText("Enable shared bundle pool");
enabledButton.setSelection(poolEnabled);
enabledButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
enabled[0] = enabledButton.getSelection();
getComposite().setEnabled(enabled[0]);
}
});
new Label(parent, SWT.NONE);
super.createUI(parent);
getComposite().setEnabled(poolEnabled);
}
@Override
protected void createButtonsForButtonBar(Composite parent)
{
super.createButtonsForButtonBar(parent);
Button button = getButton(IDialogConstants.OK_ID);
if (button != null)
{
button.setEnabled(false);
}
}
@Override
protected void elementChanged(Object element)
{
Button button = getButton(IDialogConstants.OK_ID);
if (button != null)
{
button.setEnabled(element instanceof BundlePool);
}
}
};
if (pool != null)
{
dialog.setSelectedElement(pool);
}
if (dialog.open() == AgentManagerDialog.OK)
{
enablePool(enabled[0]);
pool = (BundlePool)dialog.getSelectedElement();
}
}
public boolean refreshJREs()
{
if (variablePage != null)
{
return variablePage.refreshJREs();
}
return false;
}
public void showAbout()
{
String version = SelfUpdate.getProductVersion();
new AboutDialog(getShell(), version).open();
}
public void productSelected(Product product)
{
variablePage.setProduct(product);
switchToPage(variablePage);
}
public SimpleInstallerPage getTopPage()
{
return (SimpleInstallerPage)stackLayout.topControl;
}
private void doSwitch(final SimpleInstallerPage oldPage, final SimpleInstallerPage newPage)
{
if (oldPage != null)
{
oldPage.aboutToHide();
}
stackLayout.topControl = newPage;
stack.layout();
clearMessage();
newPage.aboutToShow();
newPage.setFocus();
}
private void switchToPage(final SimpleInstallerPage newPage)
{
if (newPage != null)
{
SimpleInstallerPage oldPage = pageStack.peek();
if (oldPage == null || oldPage != newPage)
{
pageStack.push(newPage);
doSwitch(oldPage, newPage);
}
}
}
public void switchToAdvancedMode()
{
installer.setConfigurationResources(Collections.<Resource> emptySet());
setReturnCode(RETURN_ADVANCED);
exitSelected();
}
public void restart()
{
setReturnCode(RETURN_RESTART);
exitSelected();
}
protected void exitQuiet()
{
super.exitSelected();
}
@Override
protected void exitSelected()
{
for (SimpleInstallerPage page : pageStack)
{
if (page instanceof SimpleVariablePage)
{
SimpleVariablePage variablePage = (SimpleVariablePage)page;
if (!variablePage.promptLaunchProduct("You're about to exit the installer"))
{
return;
}
break;
}
}
exitQuiet();
}
public void backSelected()
{
if (pageStack.size() <= 1)
{
return;
}
SimpleInstallerPage oldPage = pageStack.pop();
SimpleInstallerPage newPage = pageStack.peek();
doSwitch(oldPage, newPage);
}
public void showMessage(String message, SimpleMessageOverlay.Type type, boolean dismissAutomatically)
{
showMessage(message, type, dismissAutomatically, null);
}
public void showMessage(String message, SimpleMessageOverlay.Type type, boolean dismissAutomatically, Runnable action)
{
showMessage(message, type, dismissAutomatically, action, null);
}
public void showMessage(String message, SimpleMessageOverlay.Type type, boolean dismissAutomatically, Runnable action, Runnable closeAction)
{
// Check if we can reuse the current message to reduce flickering.
if (currentMessage == null || currentMessage.getType() != type || currentMessage.isDismissAutomatically() != dismissAutomatically
|| currentMessage.getAction() != action || currentMessage.getCloseAction() != closeAction)
{
clearMessage();
final Control originalFocusControl = getShell().getDisplay().getFocusControl();
if (originalFocusControl != null)
{
UIUtil.asyncExec(originalFocusControl, new Runnable()
{
public void run()
{
Control focusControl = getShell().getDisplay().getFocusControl();
if (focusControl != originalFocusControl)
{
originalFocusControl.setFocus();
}
}
});
}
currentMessage = new SimpleMessageOverlay(this, type, new ControlRelocator()
{
public void relocate(Control control)
{
Rectangle bounds = SimpleInstallerDialog.this.getBounds();
int x = bounds.x + 5;
int y = bounds.y + 24;
int width = bounds.width - 9;
// Depending on the current page, the height varies.
int height = pageStack.peek() instanceof SimpleProductPage ? 87 : 70;
control.setBounds(x, y, width, height);
}
}, dismissAutomatically, action, closeAction);
}
currentMessage.setMessage(message);
currentMessage.setVisible(true);
}
public void clearMessage()
{
if (currentMessage != null)
{
if (!currentMessage.isDisposed())
{
currentMessage.close();
}
currentMessage = null;
}
}
public void showReadme(java.net.URI readmeURI)
{
if (readmePage != null)
{
readmePage.setReadmeURI(readmeURI);
switchToPage(readmePage);
}
else
{
OS.INSTANCE.openSystemBrowser(readmeURI.toString());
}
}
public void showInstallationLog(File installationLogFile)
{
installationLogPage.setInstallationLogFile(installationLogFile);
switchToPage(installationLogPage);
}
public void showKeepInstaller()
{
switchToPage(keepInstallerPage);
}
@Override
public void dispose()
{
// Ensure that no Browser widget has the focus. See bug 466902.
menuButton.setFocus();
super.dispose();
}
public static Font getFont(int relativeHeight, String style)
{
String height = relativeHeight == 0 ? "" : relativeHeight > 0 ? "+" + relativeHeight : Integer.toString(relativeHeight);
return SetupInstallerPlugin.getFont(getDefaultFont(), org.eclipse.emf.common.util.URI.createURI("font:///" + height + "/" + style));
}
static Font getDefaultFont()
{
if (defaultFont == null)
{
defaultFont = JFaceResources.getFont(SetupInstallerPlugin.FONT_LABEL_DEFAULT);
if (defaultFont == null)
{
defaultFont = UIUtil.getDisplay().getSystemFont();
}
}
return defaultFont;
}
static Point getDefaultSize(Drawable drawable)
{
if (defaultSize == null)
{
defaultSize = computeSize(drawable, getDefaultFont(), 37, 38);
}
return defaultSize;
}
static Point computeSize(Drawable drawable, Font font, int x, int y)
{
GC gc = new GC(drawable);
gc.setFont(font);
try
{
int height = gc.getFontMetrics().getHeight();
int totalWidth = height * x;
int totalHeight = height * y;
return new Point(totalWidth, totalHeight);
}
finally
{
gc.dispose();
}
}
static String getCSS()
{
if (css == null)
{
try
{
css = readBundleResource("html/css/simpleInstaller.css");
}
catch (IOException ex)
{
SetupInstallerPlugin.INSTANCE.log(ex);
}
}
return css;
}
static String getPageTemplate()
{
if (pageTemplate == null)
{
try
{
pageTemplate = readBundleResource("html/PageTemplate.html");
// Embed CSS
pageTemplate = pageTemplate.replace("%INSTALLER_CSS%", SimpleInstallerDialog.getCSS());
}
catch (IOException ex)
{
SetupInstallerPlugin.INSTANCE.log(ex);
}
}
return pageTemplate;
}
static String getProductTemplate()
{
if (productTemplate == null)
{
try
{
productTemplate = readBundleResource("html/ProductTemplate.html");
}
catch (IOException ex)
{
SetupInstallerPlugin.INSTANCE.log(ex);
}
}
return productTemplate;
}
static String getProductTemplateLarge()
{
if (productTemplateLarge == null)
{
try
{
productTemplateLarge = readBundleResource("html/ProductTemplateLarge.html");
}
catch (IOException ex)
{
SetupInstallerPlugin.INSTANCE.log(ex);
}
}
return productTemplateLarge;
}
private static String readBundleResource(final String name) throws IOException
{
try
{
BundleFile root = SetupInstallerPlugin.INSTANCE.getRootFile();
BundleFile child = root.getChild(name);
return child.getContentsString();
}
catch (Exception ex)
{
throw new IOExceptionWithCause(ex);
}
}
/**
* @author Eike Stepper
*/
private final class UpdateSearcher extends Thread
{
private Display display;
public UpdateSearcher(Display display)
{
super("Simple Update Searcher");
this.display = display;
}
@Override
public void run()
{
try
{
User user = getInstaller().getUser();
updateResolution = SelfUpdate.resolve(user, null);
if (updateResolution != null && !display.isDisposed())
{
display.asyncExec(new Runnable()
{
public void run()
{
updateAvailable(true);
}
});
}
}
catch (CoreException ex)
{
SetupInstallerPlugin.INSTANCE.log(ex);
}
}
}
/**
* @author Eike Stepper
*/
private static final class PageStack extends LinkedList<SimpleInstallerPage>
{
private static final long serialVersionUID = 1L;
@Override
public void push(SimpleInstallerPage page)
{
addLast(page);
}
@Override
public SimpleInstallerPage pop()
{
return removeLast();
}
@Override
public SimpleInstallerPage peek()
{
return isEmpty() ? null : getLast();
}
}
}