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