X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2Finstall%2FInstallDialog.java;fp=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2Finstall%2FInstallDialog.java;h=257d688bd32c2c71ec6c2870119af4a3d9945b93;hp=dda30e5679ffdde25a9e0cd7f74fa134002abead;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDialog.java b/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDialog.java index dda30e567..257d688bd 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDialog.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDialog.java @@ -1,584 +1,584 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.simantics.project.management.install; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.equinox.internal.provisional.p2.installer.IInstallOperation; -import org.eclipse.equinox.internal.provisional.p2.installer.InstallDescription; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.FillLayout; -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.DirectoryDialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.ProgressBar; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.simantics.project.internal.Activator; - -/** - * The install wizard that drives the install. This dialog is used for user input - * prior to the install, progress feedback during the install, and displaying results - * at the end of the install. - */ -public class InstallDialog { - /** - * A progress monitor implementation that asynchronously updates the progress bar. - */ - class Monitor implements IProgressMonitor { - - boolean canceled = false, running = false; - String subTaskName = ""; //$NON-NLS-1$ - double totalWork, usedWork; - - public void beginTask(final String name, final int work) { - totalWork = work; - running = true; - update(); - } - - public void done() { - running = false; - usedWork = totalWork; - update(); - } - - public void internalWorked(double work) { - usedWork = Math.min(usedWork + work, totalWork); - update(); - } - - public boolean isCanceled() { - return returnCode == CANCEL; - } - - public void setCanceled(boolean value) { - returnCode = CANCEL; - } - - public void setTaskName(String name) { - subTaskName = name == null ? "" : name; //$NON-NLS-1$ - update(); - } - - public void subTask(String name) { - subTaskName = name == null ? "" : name; //$NON-NLS-1$ - update(); - } - - void update() { - Display display = getDisplay(); - if (display == null) - return; - display.asyncExec(new Runnable() { - public void run() { - Shell theShell = getShell(); - if (theShell == null || theShell.isDisposed()) - return; - progressSubTask.setText(shorten(subTaskName)); - if (progressBar.isDisposed()) - return; - progressBar.setVisible(running); - progressBar.setMaximum(1000); - progressBar.setMinimum(0); - int value = (int) (usedWork / totalWork * 1000); - if (progressBar.getSelection() < value) - progressBar.setSelection(value); - } - - private String shorten(String text) { - if (text.length() <= 64) - return text; - int len = text.length(); - return text.substring(0, 30) + "..." + text.substring(len - 30, len); //$NON-NLS-1$ - } - }); - } - - public void worked(int work) { - internalWorked(work); - } - } - - /** - * Encapsulates a result passed from an operation running in a background - * thread to the UI thread. - */ - static class Result { - private boolean done; - private IStatus status; - - synchronized void done() { - done = true; - } - - synchronized void failed(Throwable t) { - String msg = "Internal error"; - status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, msg, t); - } - - synchronized IStatus getStatus() { - return status; - } - - synchronized boolean isDone() { - return done; - } - - public void setStatus(IStatus status) { - this.status = status; - } - } - - private static final int BUTTON_WIDTH = 100; - private static final int CANCEL = 1; - private static final int OK = 0; - - private Button cancelButton; - private Composite contents; - private Button okButton; - - ProgressBar progressBar; - Label progressSubTask; - Label progressTask; - - int returnCode = -1; - - private Button settingsBrowse; - private Label settingsExplain; - private Composite settingsGroup; - private Text settingsLocation; - private Label settingsLocationLabel; - private Button settingsShared; - private Button settingsStandalone; - - private Shell shell; - - private boolean waitingForClose = false; - private Button proxySettingsButton; - private Button manualProxyTypeCheckBox; - - /** - * Creates and opens a progress monitor dialog. - */ - public InstallDialog() { - createShell(); - progressTask = new Label(contents, SWT.WRAP | SWT.LEFT); - progressTask.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - createInstallSettingsControls(); - createProgressControls(); - createButtonBar(); - - shell.pack(); - shell.layout(); - shell.open(); - } - - protected void browsePressed() { - DirectoryDialog dirDialog = new DirectoryDialog(shell); - dirDialog.setMessage("Select location"); - String location = dirDialog.open(); - if (location == null) - location = ""; //$NON-NLS-1$ - settingsLocation.setText(location); - validateInstallSettings(); - } - - protected void buttonPressed(int code) { - returnCode = code; - if (waitingForClose) - close(); - //grey out the cancel button to indicate the request was heard - if (code == CANCEL && !cancelButton.isDisposed()) - cancelButton.setEnabled(false); - } - - public void close() { - if (shell == null) - return; - if (!shell.isDisposed()) - shell.dispose(); - shell = null; - } - - private void createButtonBar() { - Composite buttonBar = new Composite(contents, SWT.NONE); - GridData data = new GridData(GridData.FILL_HORIZONTAL); - data.horizontalAlignment = SWT.RIGHT; - buttonBar.setLayoutData(data); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - layout.makeColumnsEqualWidth = true; - layout.marginHeight = 0; - layout.marginWidth = 0; - buttonBar.setLayout(layout); - - okButton = new Button(buttonBar, SWT.PUSH); - data = new GridData(BUTTON_WIDTH, SWT.DEFAULT); - okButton.setLayoutData(data); - okButton.setText("Install"); - okButton.setEnabled(false); - okButton.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - buttonPressed(OK); - } - }); - - cancelButton = new Button(buttonBar, SWT.PUSH); - data = new GridData(BUTTON_WIDTH, SWT.DEFAULT); - cancelButton.setLayoutData(data); - cancelButton.setText("Cancel"); - cancelButton.setEnabled(false); - cancelButton.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - buttonPressed(CANCEL); - } - }); - } - - /** - * Creates the controls to prompt for the agent and install locations. - */ - private void createInstallSettingsControls() { - settingsGroup = new Composite(contents, SWT.NONE); - GridLayout layout = new GridLayout(); - settingsGroup.setLayout(layout); - settingsGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Listener validateListener = new Listener() { - public void handleEvent(Event event) { - validateInstallSettings(); - } - }; - - //The group asking for the product install directory - Group installLocationGroup = new Group(settingsGroup, SWT.NONE); - installLocationGroup.setLayout(new GridLayout()); - installLocationGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - installLocationGroup.setText("Location"); - settingsLocationLabel = new Label(installLocationGroup, SWT.NONE); - settingsLocationLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - settingsLocationLabel.setText("Location"); - - //The sub-group with text entry field and browse button - Composite locationFieldGroup = new Composite(installLocationGroup, SWT.NONE); - locationFieldGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - layout = new GridLayout(); - layout.numColumns = 2; - layout.makeColumnsEqualWidth = false; - locationFieldGroup.setLayout(layout); - settingsLocation = new Text(locationFieldGroup, SWT.SINGLE | SWT.BORDER); - settingsLocation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - settingsLocation.addListener(SWT.Modify, validateListener); - settingsLocation.addKeyListener(new KeyAdapter() { - public void keyReleased(KeyEvent event) { - if (event.character == SWT.CR || event.character == SWT.KEYPAD_CR) - buttonPressed(OK); - } - }); - settingsBrowse = new Button(locationFieldGroup, SWT.PUSH); - settingsBrowse.setLayoutData(new GridData(BUTTON_WIDTH, SWT.DEFAULT)); - settingsBrowse.setText("Browse"); - settingsBrowse.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - browsePressed(); - } - }); - - //Create the radio button group asking for the kind of install (shared vs. standalone) - Group installKindGroup = new Group(settingsGroup, SWT.NONE); - installKindGroup.setText("Layout"); - installKindGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - installKindGroup.setLayout(new GridLayout()); - settingsStandalone = new Button(installKindGroup, SWT.RADIO); - settingsStandalone.setText("Standalone"); - settingsStandalone.addListener(SWT.Selection, validateListener); - settingsStandalone.setSelection(true); - settingsShared = new Button(installKindGroup, SWT.RADIO); - settingsShared.setText("Shared"); - settingsShared.addListener(SWT.Selection, validateListener); - settingsExplain = new Label(installKindGroup, SWT.WRAP); - GridData data = new GridData(SWT.DEFAULT, 40); - data.grabExcessHorizontalSpace = true; - data.horizontalAlignment = GridData.FILL; - settingsExplain.setLayoutData(data); - settingsExplain.setText("..."); - - //The group asking for the product proxy configuration - Group proxySettingsGroup = new Group(settingsGroup, SWT.NONE); - proxySettingsGroup.setLayout(new GridLayout()); - proxySettingsGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - proxySettingsGroup.setText("Proxy"); - - //The sub-group with check box, label entry field and settings button - Composite proxySettingsFieldGroup = new Composite(proxySettingsGroup, SWT.NONE); - proxySettingsFieldGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - layout = new GridLayout(); - layout.numColumns = 3; - layout.makeColumnsEqualWidth = false; - proxySettingsFieldGroup.setLayout(layout); - - manualProxyTypeCheckBox = new Button(proxySettingsFieldGroup, SWT.CHECK); - manualProxyTypeCheckBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - manualProxyTypeCheckBox.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { -// IProxyService proxies = (IProxyService) InstallApplication.getService(InstallerActivator.getDefault().getContext(), IProxyService.class.getName()); -// if (proxies != null) { -// //When the manual check box is selected the system properties should be disabled. -// //This cases the net component to switch to manual proxy provider. -// proxies.setSystemProxiesEnabled(!manualProxyTypeCheckBox.getSelection()); -// if (proxySettingsButton != null) { -// proxySettingsButton.setEnabled(manualProxyTypeCheckBox.getSelection()); -// } -// } else { - openMessage("Failed to set proxy", SWT.ICON_ERROR | SWT.OK); -// } - } - }); - manualProxyTypeCheckBox.setText("Manual"); - proxySettingsButton = new Button(proxySettingsFieldGroup, SWT.PUSH); - proxySettingsButton.setLayoutData(new GridData(BUTTON_WIDTH, SWT.DEFAULT)); - proxySettingsButton.setText("Settings"); - proxySettingsButton.setEnabled(manualProxyTypeCheckBox.getSelection()); - proxySettingsButton.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - //IProxyService proxies = (IProxyService) InstallApplication.getService(InstallerActivator.getDefault().getContext(), IProxyService.class.getName()); - //if (proxies != null) { - // ProxiesDialog proxiesDialog = new ProxiesDialog(proxies); - // proxiesDialog.open(); - //} else { - openMessage("Failed to set proxy", SWT.ICON_ERROR | SWT.OK); - //} - } - }); - - //make the entire group invisible until we actually need to prompt for locations - settingsGroup.setVisible(false); - } - - private void createProgressControls() { - progressBar = new ProgressBar(contents, SWT.HORIZONTAL | SWT.SMOOTH); - progressBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - progressBar.setVisible(false); - progressSubTask = new Label(contents, SWT.WRAP | SWT.LEFT); - progressSubTask.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - } - - private void createShell() { - shell = new Shell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.MIN | SWT.RESIZE); - shell.setBounds(300, 200, 600, 400); - shell.setText("Installer"); - shell.setLayout(new FillLayout()); - contents = new Composite(shell, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.marginWidth = 15; - layout.marginHeight = 15; - contents.setLayout(layout); - } - - public Display getDisplay() { - Shell theShell = shell; - if (theShell == null || theShell.isDisposed()) - return null; - return theShell.getDisplay(); - } - - public Shell getShell() { - return shell; - } - - /** - * Asks the user to close the dialog, and returns once the dialog is closed. - */ - public void promptForClose(String message) { - Display display = getDisplay(); - if (display == null) - return; - progressTask.setText(message); - progressSubTask.setText(""); //$NON-NLS-1$ - progressBar.setVisible(false); - okButton.setVisible(false); - cancelButton.setText("Close"); - cancelButton.setEnabled(true); - waitingForClose = true; - while (shell != null && !shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - } - - public boolean promptForLaunch(InstallDescription description) { - Display display = getDisplay(); - if (display == null) - return false; - progressTask.setText(NLS.bind("Starting", description.getProductName())); - progressSubTask.setText(""); //$NON-NLS-1$ - progressBar.setVisible(false); - okButton.setText("Launch"); - okButton.setVisible(true); - cancelButton.setText("Close"); - cancelButton.setVisible(true); - waitingForClose = true; - while (shell != null && !shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - return returnCode == OK; - } - - /** - * Prompts the user for the install location, and whether the install should - * be shared or standalone. - */ - public void promptForLocations(InstallDescription description) { - progressTask.setText(NLS.bind("Location", description.getProductName())); - okButton.setText("Install"); - okButton.setVisible(true); - cancelButton.setText("Cancel"); - cancelButton.setEnabled(true); - settingsGroup.setVisible(true); - validateInstallSettings(); - Display display = getDisplay(); - returnCode = -1; - while (returnCode == -1 && shell != null && !shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - if (returnCode == CANCEL) - close(); - if (shell == null || shell.isDisposed()) - throw new OperationCanceledException(); - setInstallSettingsEnablement(false); - Path location = new Path(settingsLocation.getText()); - description.setInstallLocation(location); - if (settingsStandalone.getSelection()) { - //force everything to be co-located regardless of what values were set in the install description - description.setAgentLocation(location.append("p2")); //$NON-NLS-1$ - description.setBundleLocation(location); - } else { - if (description.getAgentLocation() == null) - description.setAgentLocation(new Path(System.getProperty("user.home")).append(".p2/")); //$NON-NLS-1$ //$NON-NLS-2$ - //use bundle pool location specified in install description - //by default this will be null, causing the bundle pool to be nested in the agent location - } - okButton.setVisible(false); - } - - /** - * This method runs the given operation in the context of a progress dialog. - * The dialog is opened automatically prior to starting the operation, and closed - * automatically upon completion. - *

- * This method must be called from the UI thread. The operation will be - * executed outside the UI thread. - * - * @param operation The operation to run - * @return The result of the operation - */ - public IStatus run(final IInstallOperation operation) { - final Result result = new Result(); - Thread thread = new Thread() { - public void run() { - try { - result.setStatus(operation.install(new Monitor())); - } catch (ThreadDeath t) { - //must rethrow or the thread won't die - throw t; - } catch (RuntimeException t) { - result.failed(t); - } catch (Error t) { - result.failed(t); - } finally { - Display display = getDisplay(); - //ensure all events from the operation have run - if (display != null) { - display.syncExec(new Runnable() { - public void run() { - //do nothing - } - }); - } - result.done(); - //wake the event loop - if (display != null) - display.wake(); - } - } - }; - waitingForClose = false; - progressTask.setText("Installing"); - cancelButton.setText("Cancel"); - thread.start(); - Display display = getDisplay(); - while (!result.isDone()) { - if (!display.readAndDispatch()) - display.sleep(); - } - return result.getStatus(); - } - - private void setInstallSettingsEnablement(boolean value) { - settingsLocation.setEnabled(value); - settingsShared.setEnabled(value); - settingsStandalone.setEnabled(value); - settingsGroup.setEnabled(value); - settingsExplain.setEnabled(value); - settingsBrowse.setEnabled(value); - settingsLocationLabel.setEnabled(value); - } - - public void setMessage(String message) { - if (progressTask != null && !progressTask.isDisposed()) - progressTask.setText(message); - } - - /** - * Validates that the user has correctly entered all required install settings. - */ - void validateInstallSettings() { - boolean enabled = settingsStandalone.getSelection() || settingsShared.getSelection(); - enabled &= Path.ROOT.isValidPath(settingsLocation.getText()); - if (enabled) { - //make sure the install location is an absolute path - IPath location = new Path(settingsLocation.getText()); - enabled &= location.isAbsolute(); - } - okButton.setEnabled(enabled); - - if (settingsStandalone.getSelection()) - settingsExplain.setText("Standalone..."); - else - settingsExplain.setText("Shared..."); - } - - private void openMessage(String msg, int style) { - MessageBox messageBox = new MessageBox(Display.getDefault().getActiveShell(), style); - messageBox.setMessage(msg); - messageBox.open(); - } +/******************************************************************************* + * Copyright (c) 2007, 2008 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.simantics.project.management.install; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.provisional.p2.installer.IInstallOperation; +import org.eclipse.equinox.internal.provisional.p2.installer.InstallDescription; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; +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.DirectoryDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.ProgressBar; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.simantics.project.internal.Activator; + +/** + * The install wizard that drives the install. This dialog is used for user input + * prior to the install, progress feedback during the install, and displaying results + * at the end of the install. + */ +public class InstallDialog { + /** + * A progress monitor implementation that asynchronously updates the progress bar. + */ + class Monitor implements IProgressMonitor { + + boolean canceled = false, running = false; + String subTaskName = ""; //$NON-NLS-1$ + double totalWork, usedWork; + + public void beginTask(final String name, final int work) { + totalWork = work; + running = true; + update(); + } + + public void done() { + running = false; + usedWork = totalWork; + update(); + } + + public void internalWorked(double work) { + usedWork = Math.min(usedWork + work, totalWork); + update(); + } + + public boolean isCanceled() { + return returnCode == CANCEL; + } + + public void setCanceled(boolean value) { + returnCode = CANCEL; + } + + public void setTaskName(String name) { + subTaskName = name == null ? "" : name; //$NON-NLS-1$ + update(); + } + + public void subTask(String name) { + subTaskName = name == null ? "" : name; //$NON-NLS-1$ + update(); + } + + void update() { + Display display = getDisplay(); + if (display == null) + return; + display.asyncExec(new Runnable() { + public void run() { + Shell theShell = getShell(); + if (theShell == null || theShell.isDisposed()) + return; + progressSubTask.setText(shorten(subTaskName)); + if (progressBar.isDisposed()) + return; + progressBar.setVisible(running); + progressBar.setMaximum(1000); + progressBar.setMinimum(0); + int value = (int) (usedWork / totalWork * 1000); + if (progressBar.getSelection() < value) + progressBar.setSelection(value); + } + + private String shorten(String text) { + if (text.length() <= 64) + return text; + int len = text.length(); + return text.substring(0, 30) + "..." + text.substring(len - 30, len); //$NON-NLS-1$ + } + }); + } + + public void worked(int work) { + internalWorked(work); + } + } + + /** + * Encapsulates a result passed from an operation running in a background + * thread to the UI thread. + */ + static class Result { + private boolean done; + private IStatus status; + + synchronized void done() { + done = true; + } + + synchronized void failed(Throwable t) { + String msg = "Internal error"; + status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, msg, t); + } + + synchronized IStatus getStatus() { + return status; + } + + synchronized boolean isDone() { + return done; + } + + public void setStatus(IStatus status) { + this.status = status; + } + } + + private static final int BUTTON_WIDTH = 100; + private static final int CANCEL = 1; + private static final int OK = 0; + + private Button cancelButton; + private Composite contents; + private Button okButton; + + ProgressBar progressBar; + Label progressSubTask; + Label progressTask; + + int returnCode = -1; + + private Button settingsBrowse; + private Label settingsExplain; + private Composite settingsGroup; + private Text settingsLocation; + private Label settingsLocationLabel; + private Button settingsShared; + private Button settingsStandalone; + + private Shell shell; + + private boolean waitingForClose = false; + private Button proxySettingsButton; + private Button manualProxyTypeCheckBox; + + /** + * Creates and opens a progress monitor dialog. + */ + public InstallDialog() { + createShell(); + progressTask = new Label(contents, SWT.WRAP | SWT.LEFT); + progressTask.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + createInstallSettingsControls(); + createProgressControls(); + createButtonBar(); + + shell.pack(); + shell.layout(); + shell.open(); + } + + protected void browsePressed() { + DirectoryDialog dirDialog = new DirectoryDialog(shell); + dirDialog.setMessage("Select location"); + String location = dirDialog.open(); + if (location == null) + location = ""; //$NON-NLS-1$ + settingsLocation.setText(location); + validateInstallSettings(); + } + + protected void buttonPressed(int code) { + returnCode = code; + if (waitingForClose) + close(); + //grey out the cancel button to indicate the request was heard + if (code == CANCEL && !cancelButton.isDisposed()) + cancelButton.setEnabled(false); + } + + public void close() { + if (shell == null) + return; + if (!shell.isDisposed()) + shell.dispose(); + shell = null; + } + + private void createButtonBar() { + Composite buttonBar = new Composite(contents, SWT.NONE); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalAlignment = SWT.RIGHT; + buttonBar.setLayoutData(data); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = true; + layout.marginHeight = 0; + layout.marginWidth = 0; + buttonBar.setLayout(layout); + + okButton = new Button(buttonBar, SWT.PUSH); + data = new GridData(BUTTON_WIDTH, SWT.DEFAULT); + okButton.setLayoutData(data); + okButton.setText("Install"); + okButton.setEnabled(false); + okButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + buttonPressed(OK); + } + }); + + cancelButton = new Button(buttonBar, SWT.PUSH); + data = new GridData(BUTTON_WIDTH, SWT.DEFAULT); + cancelButton.setLayoutData(data); + cancelButton.setText("Cancel"); + cancelButton.setEnabled(false); + cancelButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + buttonPressed(CANCEL); + } + }); + } + + /** + * Creates the controls to prompt for the agent and install locations. + */ + private void createInstallSettingsControls() { + settingsGroup = new Composite(contents, SWT.NONE); + GridLayout layout = new GridLayout(); + settingsGroup.setLayout(layout); + settingsGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Listener validateListener = new Listener() { + public void handleEvent(Event event) { + validateInstallSettings(); + } + }; + + //The group asking for the product install directory + Group installLocationGroup = new Group(settingsGroup, SWT.NONE); + installLocationGroup.setLayout(new GridLayout()); + installLocationGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + installLocationGroup.setText("Location"); + settingsLocationLabel = new Label(installLocationGroup, SWT.NONE); + settingsLocationLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + settingsLocationLabel.setText("Location"); + + //The sub-group with text entry field and browse button + Composite locationFieldGroup = new Composite(installLocationGroup, SWT.NONE); + locationFieldGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + locationFieldGroup.setLayout(layout); + settingsLocation = new Text(locationFieldGroup, SWT.SINGLE | SWT.BORDER); + settingsLocation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + settingsLocation.addListener(SWT.Modify, validateListener); + settingsLocation.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent event) { + if (event.character == SWT.CR || event.character == SWT.KEYPAD_CR) + buttonPressed(OK); + } + }); + settingsBrowse = new Button(locationFieldGroup, SWT.PUSH); + settingsBrowse.setLayoutData(new GridData(BUTTON_WIDTH, SWT.DEFAULT)); + settingsBrowse.setText("Browse"); + settingsBrowse.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + browsePressed(); + } + }); + + //Create the radio button group asking for the kind of install (shared vs. standalone) + Group installKindGroup = new Group(settingsGroup, SWT.NONE); + installKindGroup.setText("Layout"); + installKindGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + installKindGroup.setLayout(new GridLayout()); + settingsStandalone = new Button(installKindGroup, SWT.RADIO); + settingsStandalone.setText("Standalone"); + settingsStandalone.addListener(SWT.Selection, validateListener); + settingsStandalone.setSelection(true); + settingsShared = new Button(installKindGroup, SWT.RADIO); + settingsShared.setText("Shared"); + settingsShared.addListener(SWT.Selection, validateListener); + settingsExplain = new Label(installKindGroup, SWT.WRAP); + GridData data = new GridData(SWT.DEFAULT, 40); + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + settingsExplain.setLayoutData(data); + settingsExplain.setText("..."); + + //The group asking for the product proxy configuration + Group proxySettingsGroup = new Group(settingsGroup, SWT.NONE); + proxySettingsGroup.setLayout(new GridLayout()); + proxySettingsGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + proxySettingsGroup.setText("Proxy"); + + //The sub-group with check box, label entry field and settings button + Composite proxySettingsFieldGroup = new Composite(proxySettingsGroup, SWT.NONE); + proxySettingsFieldGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + layout = new GridLayout(); + layout.numColumns = 3; + layout.makeColumnsEqualWidth = false; + proxySettingsFieldGroup.setLayout(layout); + + manualProxyTypeCheckBox = new Button(proxySettingsFieldGroup, SWT.CHECK); + manualProxyTypeCheckBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + manualProxyTypeCheckBox.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { +// IProxyService proxies = (IProxyService) InstallApplication.getService(InstallerActivator.getDefault().getContext(), IProxyService.class.getName()); +// if (proxies != null) { +// //When the manual check box is selected the system properties should be disabled. +// //This cases the net component to switch to manual proxy provider. +// proxies.setSystemProxiesEnabled(!manualProxyTypeCheckBox.getSelection()); +// if (proxySettingsButton != null) { +// proxySettingsButton.setEnabled(manualProxyTypeCheckBox.getSelection()); +// } +// } else { + openMessage("Failed to set proxy", SWT.ICON_ERROR | SWT.OK); +// } + } + }); + manualProxyTypeCheckBox.setText("Manual"); + proxySettingsButton = new Button(proxySettingsFieldGroup, SWT.PUSH); + proxySettingsButton.setLayoutData(new GridData(BUTTON_WIDTH, SWT.DEFAULT)); + proxySettingsButton.setText("Settings"); + proxySettingsButton.setEnabled(manualProxyTypeCheckBox.getSelection()); + proxySettingsButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + //IProxyService proxies = (IProxyService) InstallApplication.getService(InstallerActivator.getDefault().getContext(), IProxyService.class.getName()); + //if (proxies != null) { + // ProxiesDialog proxiesDialog = new ProxiesDialog(proxies); + // proxiesDialog.open(); + //} else { + openMessage("Failed to set proxy", SWT.ICON_ERROR | SWT.OK); + //} + } + }); + + //make the entire group invisible until we actually need to prompt for locations + settingsGroup.setVisible(false); + } + + private void createProgressControls() { + progressBar = new ProgressBar(contents, SWT.HORIZONTAL | SWT.SMOOTH); + progressBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + progressBar.setVisible(false); + progressSubTask = new Label(contents, SWT.WRAP | SWT.LEFT); + progressSubTask.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + } + + private void createShell() { + shell = new Shell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.MIN | SWT.RESIZE); + shell.setBounds(300, 200, 600, 400); + shell.setText("Installer"); + shell.setLayout(new FillLayout()); + contents = new Composite(shell, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginWidth = 15; + layout.marginHeight = 15; + contents.setLayout(layout); + } + + public Display getDisplay() { + Shell theShell = shell; + if (theShell == null || theShell.isDisposed()) + return null; + return theShell.getDisplay(); + } + + public Shell getShell() { + return shell; + } + + /** + * Asks the user to close the dialog, and returns once the dialog is closed. + */ + public void promptForClose(String message) { + Display display = getDisplay(); + if (display == null) + return; + progressTask.setText(message); + progressSubTask.setText(""); //$NON-NLS-1$ + progressBar.setVisible(false); + okButton.setVisible(false); + cancelButton.setText("Close"); + cancelButton.setEnabled(true); + waitingForClose = true; + while (shell != null && !shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } + + public boolean promptForLaunch(InstallDescription description) { + Display display = getDisplay(); + if (display == null) + return false; + progressTask.setText(NLS.bind("Starting", description.getProductName())); + progressSubTask.setText(""); //$NON-NLS-1$ + progressBar.setVisible(false); + okButton.setText("Launch"); + okButton.setVisible(true); + cancelButton.setText("Close"); + cancelButton.setVisible(true); + waitingForClose = true; + while (shell != null && !shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + return returnCode == OK; + } + + /** + * Prompts the user for the install location, and whether the install should + * be shared or standalone. + */ + public void promptForLocations(InstallDescription description) { + progressTask.setText(NLS.bind("Location", description.getProductName())); + okButton.setText("Install"); + okButton.setVisible(true); + cancelButton.setText("Cancel"); + cancelButton.setEnabled(true); + settingsGroup.setVisible(true); + validateInstallSettings(); + Display display = getDisplay(); + returnCode = -1; + while (returnCode == -1 && shell != null && !shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + if (returnCode == CANCEL) + close(); + if (shell == null || shell.isDisposed()) + throw new OperationCanceledException(); + setInstallSettingsEnablement(false); + Path location = new Path(settingsLocation.getText()); + description.setInstallLocation(location); + if (settingsStandalone.getSelection()) { + //force everything to be co-located regardless of what values were set in the install description + description.setAgentLocation(location.append("p2")); //$NON-NLS-1$ + description.setBundleLocation(location); + } else { + if (description.getAgentLocation() == null) + description.setAgentLocation(new Path(System.getProperty("user.home")).append(".p2/")); //$NON-NLS-1$ //$NON-NLS-2$ + //use bundle pool location specified in install description + //by default this will be null, causing the bundle pool to be nested in the agent location + } + okButton.setVisible(false); + } + + /** + * This method runs the given operation in the context of a progress dialog. + * The dialog is opened automatically prior to starting the operation, and closed + * automatically upon completion. + *

+ * This method must be called from the UI thread. The operation will be + * executed outside the UI thread. + * + * @param operation The operation to run + * @return The result of the operation + */ + public IStatus run(final IInstallOperation operation) { + final Result result = new Result(); + Thread thread = new Thread() { + public void run() { + try { + result.setStatus(operation.install(new Monitor())); + } catch (ThreadDeath t) { + //must rethrow or the thread won't die + throw t; + } catch (RuntimeException t) { + result.failed(t); + } catch (Error t) { + result.failed(t); + } finally { + Display display = getDisplay(); + //ensure all events from the operation have run + if (display != null) { + display.syncExec(new Runnable() { + public void run() { + //do nothing + } + }); + } + result.done(); + //wake the event loop + if (display != null) + display.wake(); + } + } + }; + waitingForClose = false; + progressTask.setText("Installing"); + cancelButton.setText("Cancel"); + thread.start(); + Display display = getDisplay(); + while (!result.isDone()) { + if (!display.readAndDispatch()) + display.sleep(); + } + return result.getStatus(); + } + + private void setInstallSettingsEnablement(boolean value) { + settingsLocation.setEnabled(value); + settingsShared.setEnabled(value); + settingsStandalone.setEnabled(value); + settingsGroup.setEnabled(value); + settingsExplain.setEnabled(value); + settingsBrowse.setEnabled(value); + settingsLocationLabel.setEnabled(value); + } + + public void setMessage(String message) { + if (progressTask != null && !progressTask.isDisposed()) + progressTask.setText(message); + } + + /** + * Validates that the user has correctly entered all required install settings. + */ + void validateInstallSettings() { + boolean enabled = settingsStandalone.getSelection() || settingsShared.getSelection(); + enabled &= Path.ROOT.isValidPath(settingsLocation.getText()); + if (enabled) { + //make sure the install location is an absolute path + IPath location = new Path(settingsLocation.getText()); + enabled &= location.isAbsolute(); + } + okButton.setEnabled(enabled); + + if (settingsStandalone.getSelection()) + settingsExplain.setText("Standalone..."); + else + settingsExplain.setText("Shared..."); + } + + private void openMessage(String msg, int style) { + MessageBox messageBox = new MessageBox(Display.getDefault().getActiveShell(), style); + messageBox.setMessage(msg); + messageBox.open(); + } } \ No newline at end of file