View | Details | Raw Unified | Return to bug 32147 | Differences between
and this patch

Collapse All | Expand All

(-)IDEApplication.java (-70 / +294 lines)
Lines 32-38 Link Here
32
import org.eclipse.swt.SWT;
32
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.custom.BusyIndicator;
33
import org.eclipse.swt.custom.BusyIndicator;
34
import org.eclipse.swt.graphics.FontData;
34
import org.eclipse.swt.graphics.FontData;
35
import org.eclipse.swt.graphics.Image;
35
import org.eclipse.swt.graphics.RGB;
36
import org.eclipse.swt.graphics.RGB;
37
import org.eclipse.swt.widgets.Decorations;
36
38
37
import org.eclipse.jface.preference.IPreferenceNode;
39
import org.eclipse.jface.preference.IPreferenceNode;
38
import org.eclipse.jface.preference.IPreferenceStore;
40
import org.eclipse.jface.preference.IPreferenceStore;
Lines 620-682 Link Here
620
	}
622
	}
621
623
622
	public void startup() throws CoreException {
624
	public void startup() throws CoreException {
623
		/* The plugin org.eclipse.ui has being separed in
625
		// Previously this impl. managed migration from 2.0 to 2.1, which is no longer
624
		   several plugins. Copy the state files from 
626
		// required.  However, that previous impl. didn't call the parent method, so
625
		   org.eclipse.ui to org.eclipse.ui.workbench */
627
		// this empty impl. has been left to continue to prevent the parent behaviour
626
		
628
		// from being invoked.
627
		IPath locationPath = getStateLocation();
628
		File newLocation = locationPath.toFile();
629
		File oldLocation = new File(newLocation,"..//org.eclipse.ui"); //$NON-NLS-1$
630
		try {
631
			oldLocation = oldLocation.getCanonicalFile();
632
		} catch (IOException e) {
633
			// ignore
634
		}		
635
		String markerFileName = ".copiedStateFiles_Marker"; //$NON-NLS-1$
636
		File markerFile = new File(oldLocation,markerFileName);
637
		if(markerFile.exists())
638
			return;
639
			
640
		try {
641
			String list[] = newLocation.list();
642
			if(list != null && list.length != 0)
643
				return;
644
645
			String oldList[] = oldLocation.list();
646
			if(oldList == null || oldList.length == 0)
647
				return;
648
649
			byte b[] = new byte[1024];
650
			for (int i = 0; i < oldList.length; i++) {
651
				String string = oldList[i];
652
				try {
653
					File oldFile = new File(oldLocation,string);
654
					FileInputStream in = new FileInputStream(oldFile);
655
					FileOutputStream out = new FileOutputStream(new File(newLocation,string));
656
					int read = in.read(b);
657
					while(read >= 0) {
658
						out.write(b,0,read);
659
						read = in.read(b);
660
					}
661
					in.close();
662
					out.close();
663
					// Don't delete the old file since the public preferences and some 
664
					// dialog settings are still read from org.eclipse.ui.
665
					// See bug 33334. 
666
					// oldFile.delete();
667
				} catch (IOException e) {
668
					new File(newLocation,string).delete();
669
				}
670
			}
671
		} finally {
672
			try { 
673
				new FileOutputStream(markerFile).close(); 
674
			} catch (IOException e) {
675
				// ignore
676
			}
677
		}
678
	}
629
	}
679
	
630
680
	/**
631
	/**
681
	 * Initializes product-specific information that comes from the
632
	 * Initializes product-specific information that comes from the
682
	 * about.ini file of the primary feature.
633
	 * about.ini file of the primary feature.
Lines 8-21 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
12
package org.eclipse.ui.internal.ide;
11
package org.eclipse.ui.internal.ide;
13
12
13
import java.io.File;
14
import java.io.FileInputStream;
15
import java.io.FileOutputStream;
16
import java.io.IOException;
17
import java.io.OutputStream;
18
import java.net.MalformedURLException;
19
import java.net.URL;
20
import java.util.Properties;
21
14
import org.eclipse.core.boot.IPlatformRunnable;
22
import org.eclipse.core.boot.IPlatformRunnable;
15
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IConfigurationElement;
24
import org.eclipse.core.runtime.IConfigurationElement;
17
import org.eclipse.core.runtime.IExecutableExtension;
25
import org.eclipse.core.runtime.IExecutableExtension;
26
import org.eclipse.core.runtime.IStatus;
27
import org.eclipse.core.runtime.Platform;
28
import org.eclipse.core.runtime.Status;
29
import org.eclipse.jface.dialogs.MessageDialog;
30
import org.eclipse.osgi.service.datalocation.Location;
31
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Display;
32
import org.eclipse.swt.widgets.Display;
33
import org.eclipse.swt.widgets.MessageBox;
34
import org.eclipse.swt.widgets.Shell;
19
import org.eclipse.ui.PlatformUI;
35
import org.eclipse.ui.PlatformUI;
20
36
21
/**
37
/**
Lines 25-61 Link Here
25
 */
41
 */
26
public final class IDEApplication implements IPlatformRunnable, IExecutableExtension {
42
public final class IDEApplication implements IPlatformRunnable, IExecutableExtension {
27
43
44
	private static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
45
	private static final String VERSION_FILENAME = "version.ini"; //$NON-NLS-1$
46
	private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime"; //$NON-NLS-1$
47
	private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$
48
28
	/**
49
	/**
29
	 * Creates a new IDE application.
50
	 * Creates a new IDE application.
30
	 */
51
	 */
31
	public IDEApplication() {
52
	public IDEApplication() {
32
		// There is nothing to do for IDEApplication
53
		// There is nothing to do for IDEApplication
33
	}
54
	}
34
	
55
35
	/* (non-Javadoc)
56
	/* (non-Javadoc)
36
	 * @see org.eclipse.core.boot.IPlatformRunnable#run(java.lang.Object)
57
	 * @see org.eclipse.core.boot.IPlatformRunnable#run(java.lang.Object)
37
	 */
58
	 */
38
	public Object run(Object args) throws Exception {
59
	public Object run(Object args) throws Exception {
39
40
		// create and startup the display for the workbench
60
		// create and startup the display for the workbench
41
		Display display = PlatformUI.createDisplay();
61
		Display display = PlatformUI.createDisplay();
42
62
43
		try {
63
		try {
64
			Shell shell = new Shell(display);
65
			try {
66
				if (!checkInstanceLocation(shell)) {
67
					Platform.endSplash();
68
					return EXIT_OK;
69
				}
70
			} finally {
71
				if (shell != null)
72
					shell.dispose();
73
			}
74
44
			// create the workbench with this advisor and run it until it exits
75
			// create the workbench with this advisor and run it until it exits
45
			// N.B. createWorkbench remembers the advisor, and also registers the
76
			// N.B. createWorkbench remembers the advisor, and also registers
46
			// workbench globally so that all UI plug-ins can find it using
77
			// the workbench globally so that all UI plug-ins can find it using
47
			// PlatformUI.getWorkbench() or AbstractUIPlugin.getWorkbench()
78
			// PlatformUI.getWorkbench() or AbstractUIPlugin.getWorkbench()
48
			int returnCode = PlatformUI.createAndRunWorkbench(display, new IDEWorkbenchAdvisor());
79
			int returnCode = PlatformUI.createAndRunWorkbench(display,
80
					new IDEWorkbenchAdvisor());
49
81
50
			// exit the application with an appropriate return code
82
			// exit the application with an appropriate return code
51
			if (returnCode == PlatformUI.RETURN_RESTART) {
83
			return returnCode == PlatformUI.RETURN_RESTART
52
				return IPlatformRunnable.EXIT_RESTART;
84
					? EXIT_RESTART
53
			} else {
85
					: EXIT_OK;
54
				return IPlatformRunnable.EXIT_OK;
86
		} finally {
55
			}
87
			if (display != null)
56
		}
88
				display.dispose();
57
		finally {
58
			display.dispose();
59
		}
89
		}
60
	}
90
	}
61
91
Lines 64-68 Link Here
64
	 */
94
	 */
65
	public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
95
	public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
66
		// There is nothing to do for IDEApplication
96
		// There is nothing to do for IDEApplication
97
	}
98
99
	/**
100
	 * Return true if a valid workspace path has been set and false otherwise.
101
	 * Prompt for and set the path if possible and required.
102
	 * 
103
	 * @return true if a valid instance location has been set and false
104
	 *         otherwise
105
	 */
106
	private boolean checkInstanceLocation(Shell shell) {
107
		// -data @none was specified but an ide requires workspace
108
		Location instanceLoc = Platform.getInstanceLocation();
109
		if (instanceLoc == null) {
110
			MessageDialog
111
					.openError(
112
							shell,
113
							IDEWorkbenchMessages
114
									.getString("IDEApplication.workspaceMandatoryTitle"), //$NON-NLS-1$
115
							IDEWorkbenchMessages
116
									.getString("IDEApplication.workspaceMandatoryMessage")); //$NON-NLS-1$
117
			return false;
118
		}
119
120
		// -data "/valid/path", workspace already set
121
		if (instanceLoc.isSet())
122
			return true;
123
124
		// -data @noDefault or -data not specified, prompt and set
125
		URL defaultUrl = instanceLoc.getDefault();
126
		String initialDefault = defaultUrl == null ? null : defaultUrl
127
				.getFile();
128
		ChooseWorkspaceData launchData = new ChooseWorkspaceData(
129
				initialDefault);
130
131
		while (true) {
132
			URL workspaceUrl = promptForWorkspace(shell, launchData);
133
			if (workspaceUrl == null)
134
				return false;
135
136
			try {
137
				// the operation will fail if the url is not a valid
138
				// instance data area, so other checking is unneeded
139
				if (instanceLoc.setURL(workspaceUrl, true)) {
140
					launchData.writePersistedData();
141
					writeWorkspaceVersion();
142
					return true;
143
				}
144
			} catch (IllegalStateException e) {
145
				MessageDialog
146
						.openError(
147
								shell,
148
								IDEWorkbenchMessages
149
										.getString("IDEApplication.workspaceCannotBeSetTitle"), //$NON-NLS-1$
150
								IDEWorkbenchMessages
151
										.getString("IDEApplication.workspaceCannotBeSetMessage")); //$NON-NLS-1$
152
				return false;
153
			}
154
155
			// by this point it has been determined that the workspace is already
156
			// in use -- force the user to choose again
157
			MessageDialog
158
					.openError(
159
							shell,
160
							IDEWorkbenchMessages
161
									.getString("IDEApplication.workspaceInUseTitle"), //$NON-NLS-1$
162
							IDEWorkbenchMessages
163
									.getString("IDEApplication.workspaceInUseMessage")); //$NON-NLS-1$
164
		}
165
	}
166
167
	/**
168
	 * Open a workspace selection dialog on the argument shell, populating the
169
	 * argument data with the user's selection. Perform first level validation
170
	 * on the selection by comparing the version information. This method does
171
	 * not examine the runtime state (e.g., is the workspace already locked?).
172
	 * 
173
	 * @param shell
174
	 * @param launchData
175
	 * @return An URL storing the selected workspace or null if the user has
176
	 *         canceled the launch operation.
177
	 */
178
	private URL promptForWorkspace(Shell shell, ChooseWorkspaceData launchData) {
179
		URL url = null;
180
		do {
181
			new ChooseWorkspaceDialog(shell, launchData).open();
182
			String instancePath = launchData.getSelection();
183
			if (instancePath == null)
184
				return null;
185
186
			try {
187
				url = new File(instancePath).toURL();
188
			} catch (MalformedURLException e) {
189
				MessageDialog
190
					.openError(
191
						shell,
192
						IDEWorkbenchMessages
193
							.getString("IDEApplication.workspaceInvalidTitle"), //$NON-NLS-1$
194
						IDEWorkbenchMessages
195
							.getString("IDEApplication.workspaceInvalidMessage")); //$NON-NLS-1$
196
				continue;
197
			}
198
		} while (!isValidWorkspace(shell, url));
199
200
		return url;
201
	}
202
203
	/**
204
	 * Return true if the argument directory is ok to use as a workspace and
205
	 * false otherwise. A version check will be performed, and a confirmation
206
	 * box may be displayed on the argument shell if an older version is
207
	 * detected.
208
	 */
209
	private boolean isValidWorkspace(Shell shell, URL url) {
210
		String version = readWorkspaceVersion(url);
211
212
		// if the version could not be read, then there is not any existing
213
		// workspace data to trample, e.g., perhaps its a new directory that
214
		// is just starting to be used as a workspace
215
		if (version == null)
216
			return true;
217
218
		final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE);
219
		int workspace_version = Integer.parseInt(version);
220
221
		// equality test is required since any version difference (newer
222
		// or older) may result in data being trampled
223
		if (workspace_version == ide_version)
224
			return true;
225
226
		// At this point workspace has been detected to be from a version
227
		// other than the current ide version -- find out if the user wants
228
		// to use it anyhow.
229
		String title = IDEWorkbenchMessages
230
				.getString("IDEApplication.versionTitle"); //$NON-NLS-1$
231
		String message = IDEWorkbenchMessages.format(
232
				"IDEApplication.versionMessage", //$NON-NLS-1$
233
				new Object[]{url.getFile()});
234
235
		MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL
236
				| SWT.ICON_WARNING | SWT.APPLICATION_MODAL);
237
		mbox.setText(title);
238
		mbox.setMessage(message);
239
		return mbox.open() == SWT.OK;
240
	}
241
242
	/**
243
	 * Look at the argument URL for the workspace's version information. Return
244
	 * that version if found and null otherwise.
245
	 */
246
	private static String readWorkspaceVersion(URL workspace) {
247
		File versionFile = getVersionFile(workspace, false);
248
		if (versionFile == null || !versionFile.exists())
249
			return null;
250
251
		try {
252
			// Although the version file is not spec'ed to be a Java properties
253
			// file, it happens to follow the same format currently, so using
254
			// Properties to read it is convenient.
255
			Properties props = new Properties();
256
			FileInputStream is = new FileInputStream(versionFile);
257
			try {
258
				props.load(is);
259
			} finally {
260
				is.close();
261
			}
262
263
			return props.getProperty(WORKSPACE_VERSION_KEY);
264
		} catch (IOException e) {
265
			IDEWorkbenchPlugin.log("Could not read version file", new Status( //$NON-NLS-1$
266
					IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
267
					IStatus.ERROR, e.getMessage(), e));
268
			return null;
269
		}
270
	}
271
272
	/**
273
	 * Write the version of the metadata into a known file overwriting any
274
	 * existing file contents. Writing the version file isn't really crucial,
275
	 * so the function is silent about failure
276
	 */
277
	private static void writeWorkspaceVersion() {
278
		Location instanceLoc = Platform.getInstanceLocation();
279
		if (instanceLoc == null || instanceLoc.isReadOnly())
280
			return;
281
282
		File versionFile = getVersionFile(instanceLoc.getURL(), true);
283
		if (versionFile == null)
284
			return;
285
286
		OutputStream output = null;
287
		try {
288
			String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE;
289
290
			output = new FileOutputStream(versionFile);
291
			output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$
292
		} catch (IOException e) {
293
			IDEWorkbenchPlugin.log("Could not write version file", new Status( //$NON-NLS-1$
294
					IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
295
					IStatus.ERROR, e.getMessage(), e));
296
		} finally {
297
			try {
298
				if (output != null)
299
					output.close();
300
			} catch (IOException e) {
301
				// do nothing
302
			}
303
		}
304
	}
305
306
	/**
307
	 * The version file is stored in the metadata area of the workspace. This
308
	 * method returns an URL to the file or null if the directory or file does
309
	 * not exist (and the create parameter is false).
310
	 * 
311
	 * @param create
312
	 *            If the directory and file does not exist this parameter
313
	 *            controls whether it will be created.
314
	 * @return An url to the file or null if the version file does not exist or
315
	 *         could not be created.
316
	 */
317
	private static File getVersionFile(URL workspaceUrl, boolean create) {
318
		if (workspaceUrl == null)
319
			return null;
320
321
		try {
322
			// make sure the directory exists
323
			URL metaUrl = new URL(workspaceUrl, METADATA_FOLDER);
324
			File metaDir = new File(metaUrl.getFile());
325
			if (!metaDir.exists() && (!create || !metaDir.mkdir()))
326
				return null;
327
328
			// make sure the file exists
329
			URL versionUrl = new URL(metaDir.toURL(), VERSION_FILENAME);
330
			File versionFile = new File(versionUrl.getFile());
331
			if (!versionFile.exists()
332
					&& (!create || !versionFile.createNewFile()))
333
				return null;
334
335
			return versionFile;
336
		} catch (IOException e) {
337
			// cannot log because instance area has not been set
338
			return null;
339
		}
67
	}
340
	}
68
}
341
}
(-)src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java (+294 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.ide;
12
13
import java.io.File;
14
import java.io.FileReader;
15
import java.io.FileWriter;
16
import java.io.IOException;
17
import java.io.Reader;
18
import java.io.Writer;
19
import java.net.URL;
20
21
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.Platform;
23
import org.eclipse.core.runtime.Status;
24
import org.eclipse.osgi.service.datalocation.Location;
25
import org.eclipse.ui.IMemento;
26
import org.eclipse.ui.WorkbenchException;
27
import org.eclipse.ui.XMLMemento;
28
29
/**
30
 * This class stores the information behind the "Launch Workspace" dialog. The
31
 * class is able to read and write itself to a well known configuration file.
32
 */
33
public class ChooseWorkspaceData {
34
	/**
35
	 * The default max length of the recent workspace mru list.  The values
36
	 * stored in xml (both the max-length parameter and actual size of the
37
	 * list) will supersede this value. 
38
	 */
39
	private static final int RECENT_MAX_LENGTH = 5;
40
41
	/**
42
	 * The directory within the config area that will be used for the
43
	 * receiver's persisted data.
44
	 */
45
	private static final String PERS_FOLDER = "org.eclipse.ui.ide"; //$NON-NLS-1$
46
	
47
	/**
48
	 * The name of the file within the config area that will be used for
49
	 * the recever's persisted data.
50
	 * @see PERS_FOLDER
51
	 */
52
	private static final String PERS_FILENAME = "recentWorkspaces.xml"; //$NON-NLS-1$
53
	private static final int PERS_ENCODING_VERSION = 1;
54
55
	private String initialDefault;
56
	private String selection;
57
	private String[] recentWorkspaces;
58
59
	// xml tags
60
	private static interface XML {
61
		public static final String PROTOCOL = "protocol"; //$NON-NLS-1$
62
		public static final String VERSION = "version"; //$NON-NLS-1$
63
		public static final String WORKSPACE = "workspace"; //$NON-NLS-1$
64
		public static final String RECENT_WORKSPACES = "recentWorkspaces"; //$NON-NLS-1$
65
		public static final String MAX_LENGTH = "maxLength"; //$NON-NLS-1$
66
		public static final String PATH = "path"; //$NON-NLS-1$
67
	}	
68
69
	/**
70
	 * Creates a new instance, loading persistent data if its found.
71
	 */
72
	public ChooseWorkspaceData(String initialDefault) {
73
		readPersistedData();
74
		this.initialDefault = initialDefault;
75
	}
76
77
	/**
78
	 * Return the folder to be used as a default if no other information
79
	 * exists. Does not return null.
80
	 */
81
	public String getInitialDefault() {
82
		if (initialDefault == null)
83
			initialDefault = System.getProperty("user.dir")
84
					+ File.separator + "workspace";
85
		return initialDefault;
86
	}
87
88
	/**
89
	 * Return the currently selected workspace or null if nothing is selected.
90
	 */
91
	public String getSelection() {
92
		return selection;
93
	}
94
95
	/**
96
	 * Return an array of recent workspaces sorted with the most recently used at
97
	 * the start.
98
	 */
99
	public String[] getRecentWorkspaces() {
100
		return recentWorkspaces;
101
	}
102
103
	/**
104
	 * The argument workspace has been selected, update the receiver.  Does not
105
	 * persist the new values.
106
	 */
107
	public void workspaceSelected(String dir) {
108
		// this just stores the selection, it is not inserted and persisted
109
		// until the workspace is actually selected
110
		selection = dir;
111
	}
112
113
	/**
114
	 * Update the persistent store.  Call this function after the currently selected
115
	 * value has been found to be ok.
116
	 */
117
	public void writePersistedData() {
118
		Location configLoc = Platform.getConfigurationLocation();
119
		if (configLoc == null || configLoc.isReadOnly())
120
			return;
121
122
		URL persUrl = getPersistenceUrl(configLoc.getURL(), true);
123
		if (persUrl == null)
124
			return;
125
126
		// move the new selection to the front of the list
127
		if(selection != null) {
128
			String oldEntry = recentWorkspaces[0];
129
			recentWorkspaces[0] = selection;
130
			for (int i = 1; i < recentWorkspaces.length && oldEntry != null; ++i) {
131
				if (selection.equals(oldEntry))
132
					return;
133
				String tmp = recentWorkspaces[i];
134
				recentWorkspaces[i] = oldEntry;
135
				oldEntry = tmp;
136
			}
137
		}
138
139
		Writer writer = null;
140
		try {
141
			writer = new FileWriter(persUrl.getFile());
142
143
			// E.g.,
144
			//	<launchWorkspaceData>
145
			//		<protocol version="1"/>
146
			// 		<recentWorkspaces maxLength="5">
147
			//			<workspace path="C:\eclipse\workspace0"/>
148
			//			<workspace path="C:\eclipse\workspace1"/>
149
			//		</recentWorkspaces>
150
			//	</launchWorkspaceData>
151
152
			XMLMemento memento = XMLMemento.createWriteRoot("launchWorkspaceData");
153
154
			memento.createChild(XML.PROTOCOL)
155
				   .putInteger(XML.VERSION, PERS_ENCODING_VERSION);
156
157
			IMemento recentMemento = memento.createChild(XML.RECENT_WORKSPACES);
158
			recentMemento.putInteger(XML.MAX_LENGTH, recentWorkspaces.length);
159
			for(int i = 0; i < recentWorkspaces.length; ++i) {
160
				if(recentWorkspaces[i] == null)
161
					break;
162
				recentMemento.createChild(XML.WORKSPACE).putString(XML.PATH, recentWorkspaces[i]);
163
			}
164
			memento.save(writer);
165
		} catch (IOException e) {
166
			IDEWorkbenchPlugin.log("Unable to write recent workspace data", new Status( //$NON-NLS-1$
167
					IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
168
					IStatus.ERROR, e.getMessage(), e));
169
		}
170
		finally {
171
			if(writer != null)
172
				try {
173
					writer.close();
174
				} catch (IOException e1) {
175
					// do nothing
176
				}
177
		}
178
	}
179
180
	/**
181
	 * Look for and read data that might have been persisted from some previous
182
	 * run. Leave the receiver in a default state if no persistent data is
183
	 * found.
184
	 */
185
	private void readPersistedData() {
186
		URL persUrl = null;
187
188
		Location configLoc = Platform.getConfigurationLocation();
189
		if(configLoc != null)
190
			persUrl = getPersistenceUrl(configLoc.getURL(), false);
191
192
		try {
193
			// inside try to get the safe default creation in the finally
194
			// clause
195
			if (persUrl == null)
196
				return;
197
198
			// E.g.,
199
			//	<launchWorkspaceData>
200
			//		<protocol version="1"/>
201
			// 		<recentWorkspaces maxLength="5">
202
			//			<workspace path="C:\eclipse\workspace0"/>
203
			//			<workspace path="C:\eclipse\workspace1"/>
204
			//		</recentWorkspaces>
205
			//	</launchWorkspaceData>
206
207
			Reader reader = new FileReader(persUrl.getFile());
208
			XMLMemento memento = XMLMemento.createReadRoot(reader);
209
			if (memento == null || !compatibleProtocol(memento))
210
				return;
211
212
			IMemento recent = memento.getChild(XML.RECENT_WORKSPACES);
213
			if(recent == null)
214
				return;
215
216
			Integer maxLength = recent.getInteger(XML.MAX_LENGTH);
217
			int max = RECENT_MAX_LENGTH;
218
			if(maxLength != null)
219
				max = maxLength.intValue();
220
221
			IMemento indices[] = recent.getChildren(XML.WORKSPACE);
222
			if(indices == null || indices.length <= 0)
223
				return;
224
225
			// if a user has edited maxLength to be shorter than the listed
226
			// indices, accept the list (its tougher for them to retype a long
227
			// list of paths than to update a max number)
228
			max = Math.max(max, indices.length);
229
230
			recentWorkspaces = new String[max];
231
			for(int i = 0; i < indices.length; ++i) {
232
				String path = indices[i].getString(XML.PATH);
233
				if(path == null)
234
					break;
235
				recentWorkspaces[i] = path; 
236
			}
237
			return;
238
		} catch (IOException e) {
239
			// do nothing -- cannot log because instance area has not been set
240
		} catch (WorkbenchException e) {
241
			// do nothing -- cannot log because instance area has not been set
242
		}
243
		finally {
244
			// create safe default if needed
245
			if(recentWorkspaces == null)
246
				recentWorkspaces = new String[RECENT_MAX_LENGTH];
247
		}
248
	}
249
250
	/**
251
	 * Return true if the protocol used to encode the argument memento is compatible
252
	 * with the receiver's implementation and false otherwise.
253
	 */
254
	private static boolean compatibleProtocol(IMemento memento) {
255
		IMemento protocolMemento = memento.getChild(XML.PROTOCOL);
256
		if(protocolMemento == null)
257
			return false;
258
259
		Integer version = protocolMemento.getInteger(XML.VERSION);
260
		return version != null && version.intValue() == PERS_ENCODING_VERSION;
261
	}
262
263
	/**
264
	 * The workspace data is stored in the well known file pointed to by the result
265
	 * of this method.
266
	 * @param create If the directory and file does not exist this parameter
267
	 *               controls whether it will be created.
268
	 * @return An url to the file and null if it does not exist or could not
269
	 *         be created.
270
	 */
271
	private static URL getPersistenceUrl(URL baseUrl, boolean create) {
272
		if(baseUrl == null)
273
			return null;
274
275
		try {
276
			// make sure the directory exists
277
			URL url = new URL(baseUrl, PERS_FOLDER);
278
			File dir = new File(url.getFile());
279
			if (!dir.exists() && (!create || !dir.mkdir()))
280
				return null;
281
282
			// make sure the file exists
283
			url = new URL(dir.toURL(), PERS_FILENAME);
284
			File persFile = new File(url.getFile());
285
			if (!persFile.exists() && (!create || !persFile.createNewFile()))
286
				return null;
287
288
			return persFile.toURL();
289
		} catch (IOException e) {
290
			// cannot log because instance area has not been set
291
			return null;
292
		}
293
	}
294
}
(-)messages.properties (+227 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.ide;
12
13
import java.net.MalformedURLException;
14
import java.net.URL;
15
16
import org.eclipse.core.runtime.Platform;
17
import org.eclipse.jface.dialogs.IDialogConstants;
18
import org.eclipse.jface.dialogs.TitleAreaDialog;
19
import org.eclipse.jface.resource.ImageDescriptor;
20
import org.eclipse.swt.SWT;
21
import org.eclipse.swt.events.ModifyEvent;
22
import org.eclipse.swt.events.ModifyListener;
23
import org.eclipse.swt.events.SelectionAdapter;
24
import org.eclipse.swt.events.SelectionEvent;
25
import org.eclipse.swt.graphics.Image;
26
import org.eclipse.swt.layout.GridData;
27
import org.eclipse.swt.layout.GridLayout;
28
import org.eclipse.swt.widgets.Button;
29
import org.eclipse.swt.widgets.Combo;
30
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.swt.widgets.DirectoryDialog;
33
import org.eclipse.swt.widgets.Label;
34
import org.eclipse.swt.widgets.Shell;
35
36
/**
37
 * A dialog that prompts for a directory to use as a workspace.
38
 */
39
public class ChooseWorkspaceDialog extends TitleAreaDialog {
40
	private ChooseWorkspaceData launchData;
41
	private String currentSelection;
42
43
	/**
44
	 * Create a modal dialog on the arugment shell, using and updating the argument
45
	 * data object.
46
	 */
47
	public ChooseWorkspaceDialog(Shell parentShell, ChooseWorkspaceData launchData) {
48
		super(parentShell);
49
		this.launchData = launchData;
50
	}
51
52
	/**
53
	 * Creates and returns the contents of the upper part of this dialog (above
54
	 * the button bar).
55
	 * <p>
56
	 * The <code>Dialog</code> implementation of this framework method creates
57
	 * and returns a new <code>Composite</code> with no margins and spacing.
58
	 * </p>
59
	 *
60
	 * @param the parent composite to contain the dialog area
61
	 * @return the dialog area control
62
	 */
63
	protected Control createDialogArea(Composite parent) {
64
		Composite composite = (Composite) super.createDialogArea(parent);
65
		setTitle(IDEWorkbenchMessages
66
				.getString("ChooseWorkspaceDialog.dialogTitle")); //$NON-NLS-1$
67
		setMessage(IDEWorkbenchMessages
68
				.getString("ChooseWorkspaceDialog.dialogMessage")); //$NON-NLS-1$
69
		setTitleImage();
70
71
		createWorkspaceBrowseRow(composite);
72
		return composite;
73
	}
74
75
	/**
76
	 * Configures the given shell in preparation for opening this window
77
	 * in it.
78
	 * <p>
79
	 * The default implementation of this framework method
80
	 * sets the shell's image and gives it a grid layout. 
81
	 * Subclasses may extend or reimplement.
82
	 * </p>
83
	 * 
84
	 * @param shell the shell
85
	 */
86
	protected void configureShell(Shell shell) {
87
		super.configureShell(shell);
88
		shell.setText(IDEWorkbenchMessages
89
				.getString("ChooseWorkspaceDialog.dialogName")); //$NON-NLS-1$
90
	}
91
92
	/**
93
	 * Notifies that the ok button of this dialog has been pressed.
94
	 * <p>
95
	 * The <code>Dialog</code> implementation of this framework method sets
96
	 * this dialog's return code to <code>Window.OK</code>
97
	 * and closes the dialog. Subclasses may override.
98
	 * </p>
99
	 */
100
	protected void okPressed() {
101
		launchData.workspaceSelected(currentSelection);
102
		super.okPressed();
103
	}
104
105
	/**
106
	 * Notifies that the cancel button of this dialog has been pressed.
107
	 * <p>
108
	 * The <code>Dialog</code> implementation of this framework method sets
109
	 * this dialog's return code to <code>Window.CANCEL</code>
110
	 * and closes the dialog. Subclasses may override if desired.
111
	 * </p>
112
	 */
113
	protected void cancelPressed() {
114
		currentSelection = null;
115
		launchData.workspaceSelected(currentSelection);
116
		super.cancelPressed();
117
	}
118
119
	private void setTitleImage() {
120
		try {
121
			URL installURL = Platform.getPlugin(
122
					IDEWorkbenchPlugin.IDE_WORKBENCH).getDescriptor()
123
					.getInstallURL();
124
			URL url = new URL(installURL, "icons/full/wizban/newfolder_wiz.gif");//$NON-NLS-1$
125
126
			ImageDescriptor desc = ImageDescriptor.createFromURL(url);
127
			Image image = desc.createImage();
128
			if (image != null)
129
				setTitleImage(image);
130
		} catch (MalformedURLException e) {
131
			// do nothing
132
		}
133
	}
134
135
	/**
136
	 * The main area of the dialog is just a row with the current selection
137
	 * information and a drop-down of the most recently used workspaces.
138
	 */
139
	private void createWorkspaceBrowseRow(Composite parent) {
140
		Composite panel = new Composite(parent, SWT.NONE);
141
142
		GridLayout layout = new GridLayout(3, false);
143
		layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
144
		layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
145
		layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
146
		layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
147
		panel.setLayout(layout);
148
		panel.setLayoutData(new GridData(GridData.FILL_BOTH));
149
		panel.setFont(parent.getFont());
150
151
		Label label = new Label(panel, SWT.NONE);
152
		label.setText(IDEWorkbenchMessages
153
				.getString("ChooseWorkspaceDialog.workspaceEntryLabel")); //$NON-NLS-1$
154
155
		final Combo text = new Combo(panel, SWT.BORDER | SWT.LEAD
156
				| SWT.DROP_DOWN);
157
		text.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
158
				| GridData.FILL_HORIZONTAL));
159
		setInitialTextValues(text);
160
		text.addModifyListener(new ModifyListener() {
161
			public void modifyText(ModifyEvent e) {
162
				currentSelection = text.getText();
163
			}
164
		});
165
166
		Button browseButton = new Button(panel, SWT.PUSH);
167
		browseButton.setText(IDEWorkbenchMessages
168
				.getString("ChooseWorkspaceDialog.browseLabel")); //$NON-NLS-1$
169
		setButtonLayoutData(browseButton);
170
		GridData data = (GridData) browseButton.getLayoutData();
171
		data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_END;
172
		browseButton.setLayoutData(data);
173
		browseButton.addSelectionListener(new SelectionAdapter() {
174
			public void widgetSelected(SelectionEvent e) {
175
				DirectoryDialog dialog = new DirectoryDialog(getShell());
176
				dialog.setText(IDEWorkbenchMessages
177
								.getString("ChooseWorkspaceDialog.directoryBrowserTitle")); //$NON-NLS-1$
178
				dialog.setMessage(IDEWorkbenchMessages
179
								.getString("ChooseWorkspaceDialog.directoryBrowserMessage")); //$NON-NLS-1$
180
				dialog.setFilterPath(currentSelection);
181
				String dir = dialog.open();
182
				if (dir != null)
183
					text.setText(dir);
184
			}
185
		});
186
	}
187
188
	private void setInitialTextValues(Combo text) {
189
		String[] recentWorkspaces = launchData.getRecentWorkspaces();
190
		for(int i = 0; i < recentWorkspaces.length; ++i)
191
			if(recentWorkspaces[i] != null)
192
				text.add(recentWorkspaces[i]);
193
194
		currentSelection = text.getItemCount() > 0
195
				? text.getItem(0)
196
				: launchData.getInitialDefault();
197
		text.setText(currentSelection);
198
	}
199
}
Added Link Here
1568
DecorationScheduler.UpdatingTask=Updating
1568
DecorationScheduler.UpdatingTask=Updating
1569
DecorationScheduler.CalculatingTask=Calculating
1569
DecorationScheduler.CalculatingTask=Calculating
1570
DecorationScheduler.DecoratingSubtask=Decorating {0}
1570
DecorationScheduler.DecoratingSubtask=Decorating {0}
1571
ChooseWorkspaceDialog.dialogName=Workspace Launcher
1572
ChooseWorkspaceDialog.dialogTitle=Select a workspace
1573
ChooseWorkspaceDialog.dialogMessage=The workspace is where resources such as files and directories are stored.
1574
ChooseWorkspaceDialog.workspaceEntryLabel=&Workspace:
1575
ChooseWorkspaceDialog.browseLabel=&Browse...
1576
ChooseWorkspaceDialog.directoryBrowserTitle=Select Workspace Directory
1577
ChooseWorkspaceDialog.directoryBrowserMessage=Select the workspace directory to use.
1578
IDEApplication.workspaceMandatoryTitle=Workspace is Mandatory
1579
IDEApplication.workspaceMandatoryMessage=IDEs need a valid workspace; restart without the @none option.
1580
IDEApplication.workspaceInUseTitle=Workspace in Use
1581
IDEApplication.workspaceInUseMessage=Workspace in use, choose a different one.
1582
IDEApplication.workspaceInvalidTitle=Invalid Workspace
1583
IDEApplication.workspaceInvalidMessage=Selected workspace is not valid; choose a different one.
1584
IDEApplication.workspaceCannotBeSetTitle=Workspace Cannot be Set
1585
IDEApplication.workspaceCannotBeSetMessage=Error in runtime; workspace could not be set.  Exiting.
1586
IDEApplication.versionTitle = Different Workspace Version
1587
IDEApplication.versionMessage = \
1588
	This workspace was written with a different version of the product and needs to be updated.\n\n\
1589
	{0}\n\n\
1590
	Updating the workspace may make it incompatible with other versions of the product.\n\
1591
	Press OK to update the workspace and open it.  Press Cancel to select a different workspace.
1592
ChooseWorkspaceData.launchWorkspaceTag=launchWorkspaceData
1593
ChooseWorkspaceData.protocolTag=protocol
1594
ChooseWorkspaceData.versionTag=version
1595
ChooseWorkspaceData.pathTag=path
1596
ChooseWorkspaceData.recentWorkspacesTag=recentWorkspaces
1597
ChooseWorkspaceData.maxLengthTag=maxLength
1598
ChooseWorkspaceData.workspaceTag=workspace
1571
GlobalBuildAction.BuildRunningTitle=Build Is Running
1599
GlobalBuildAction.BuildRunningTitle=Build Is Running
1572
GlobalBuildAction.BuildRunningMessage=A build is currently running. Do you wish to cancel it?
1600
GlobalBuildAction.BuildRunningMessage=A build is currently running. Do you wish to cancel it?
(-)src/org/eclipse/ui/internal/ide/ChooseWorkspaceData.java (+294 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.ide;
12
13
import java.io.File;
14
import java.io.FileReader;
15
import java.io.FileWriter;
16
import java.io.IOException;
17
import java.io.Reader;
18
import java.io.Writer;
19
import java.net.URL;
20
21
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.Platform;
23
import org.eclipse.core.runtime.Status;
24
import org.eclipse.osgi.service.datalocation.Location;
25
import org.eclipse.ui.IMemento;
26
import org.eclipse.ui.WorkbenchException;
27
import org.eclipse.ui.XMLMemento;
28
29
/**
30
 * This class stores the information behind the "Launch Workspace" dialog. The
31
 * class is able to read and write itself to a well known configuration file.
32
 */
33
public class ChooseWorkspaceData {
34
	/**
35
	 * The default max length of the recent workspace mru list.  The values
36
	 * stored in xml (both the max-length parameter and actual size of the
37
	 * list) will supersede this value. 
38
	 */
39
	private static final int RECENT_MAX_LENGTH = 5;
40
41
	/**
42
	 * The directory within the config area that will be used for the
43
	 * receiver's persisted data.
44
	 */
45
	private static final String PERS_FOLDER = "org.eclipse.ui.ide"; //$NON-NLS-1$
46
	
47
	/**
48
	 * The name of the file within the config area that will be used for
49
	 * the recever's persisted data.
50
	 * @see PERS_FOLDER
51
	 */
52
	private static final String PERS_FILENAME = "recentWorkspaces.xml"; //$NON-NLS-1$
53
	private static final int PERS_ENCODING_VERSION = 1;
54
55
	private String initialDefault;
56
	private String selection;
57
	private String[] recentWorkspaces;
58
59
	// xml tags
60
	private static interface XML {
61
		public static final String PROTOCOL = "protocol"; //$NON-NLS-1$
62
		public static final String VERSION = "version"; //$NON-NLS-1$
63
		public static final String WORKSPACE = "workspace"; //$NON-NLS-1$
64
		public static final String RECENT_WORKSPACES = "recentWorkspaces"; //$NON-NLS-1$
65
		public static final String MAX_LENGTH = "maxLength"; //$NON-NLS-1$
66
		public static final String PATH = "path"; //$NON-NLS-1$
67
	}	
68
69
	/**
70
	 * Creates a new instance, loading persistent data if its found.
71
	 */
72
	public ChooseWorkspaceData(String initialDefault) {
73
		readPersistedData();
74
		this.initialDefault = initialDefault;
75
	}
76
77
	/**
78
	 * Return the folder to be used as a default if no other information
79
	 * exists. Does not return null.
80
	 */
81
	public String getInitialDefault() {
82
		if (initialDefault == null)
83
			initialDefault = System.getProperty("user.dir")
84
					+ File.separator + "workspace";
85
		return initialDefault;
86
	}
87
88
	/**
89
	 * Return the currently selected workspace or null if nothing is selected.
90
	 */
91
	public String getSelection() {
92
		return selection;
93
	}
94
95
	/**
96
	 * Return an array of recent workspaces sorted with the most recently used at
97
	 * the start.
98
	 */
99
	public String[] getRecentWorkspaces() {
100
		return recentWorkspaces;
101
	}
102
103
	/**
104
	 * The argument workspace has been selected, update the receiver.  Does not
105
	 * persist the new values.
106
	 */
107
	public void workspaceSelected(String dir) {
108
		// this just stores the selection, it is not inserted and persisted
109
		// until the workspace is actually selected
110
		selection = dir;
111
	}
112
113
	/**
114
	 * Update the persistent store.  Call this function after the currently selected
115
	 * value has been found to be ok.
116
	 */
117
	public void writePersistedData() {
118
		Location configLoc = Platform.getConfigurationLocation();
119
		if (configLoc == null || configLoc.isReadOnly())
120
			return;
121
122
		URL persUrl = getPersistenceUrl(configLoc.getURL(), true);
123
		if (persUrl == null)
124
			return;
125
126
		// move the new selection to the front of the list
127
		if(selection != null) {
128
			String oldEntry = recentWorkspaces[0];
129
			recentWorkspaces[0] = selection;
130
			for (int i = 1; i < recentWorkspaces.length && oldEntry != null; ++i) {
131
				if (selection.equals(oldEntry))
132
					return;
133
				String tmp = recentWorkspaces[i];
134
				recentWorkspaces[i] = oldEntry;
135
				oldEntry = tmp;
136
			}
137
		}
138
139
		Writer writer = null;
140
		try {
141
			writer = new FileWriter(persUrl.getFile());
142
143
			// E.g.,
144
			//	<launchWorkspaceData>
145
			//		<protocol version="1"/>
146
			// 		<recentWorkspaces maxLength="5">
147
			//			<workspace path="C:\eclipse\workspace0"/>
148
			//			<workspace path="C:\eclipse\workspace1"/>
149
			//		</recentWorkspaces>
150
			//	</launchWorkspaceData>
151
152
			XMLMemento memento = XMLMemento.createWriteRoot("launchWorkspaceData");
153
154
			memento.createChild(XML.PROTOCOL)
155
				   .putInteger(XML.VERSION, PERS_ENCODING_VERSION);
156
157
			IMemento recentMemento = memento.createChild(XML.RECENT_WORKSPACES);
158
			recentMemento.putInteger(XML.MAX_LENGTH, recentWorkspaces.length);
159
			for(int i = 0; i < recentWorkspaces.length; ++i) {
160
				if(recentWorkspaces[i] == null)
161
					break;
162
				recentMemento.createChild(XML.WORKSPACE).putString(XML.PATH, recentWorkspaces[i]);
163
			}
164
			memento.save(writer);
165
		} catch (IOException e) {
166
			IDEWorkbenchPlugin.log("Unable to write recent workspace data", new Status( //$NON-NLS-1$
167
					IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
168
					IStatus.ERROR, e.getMessage(), e));
169
		}
170
		finally {
171
			if(writer != null)
172
				try {
173
					writer.close();
174
				} catch (IOException e1) {
175
					// do nothing
176
				}
177
		}
178
	}
179
180
	/**
181
	 * Look for and read data that might have been persisted from some previous
182
	 * run. Leave the receiver in a default state if no persistent data is
183
	 * found.
184
	 */
185
	private void readPersistedData() {
186
		URL persUrl = null;
187
188
		Location configLoc = Platform.getConfigurationLocation();
189
		if(configLoc != null)
190
			persUrl = getPersistenceUrl(configLoc.getURL(), false);
191
192
		try {
193
			// inside try to get the safe default creation in the finally
194
			// clause
195
			if (persUrl == null)
196
				return;
197
198
			// E.g.,
199
			//	<launchWorkspaceData>
200
			//		<protocol version="1"/>
201
			// 		<recentWorkspaces maxLength="5">
202
			//			<workspace path="C:\eclipse\workspace0"/>
203
			//			<workspace path="C:\eclipse\workspace1"/>
204
			//		</recentWorkspaces>
205
			//	</launchWorkspaceData>
206
207
			Reader reader = new FileReader(persUrl.getFile());
208
			XMLMemento memento = XMLMemento.createReadRoot(reader);
209
			if (memento == null || !compatibleProtocol(memento))
210
				return;
211
212
			IMemento recent = memento.getChild(XML.RECENT_WORKSPACES);
213
			if(recent == null)
214
				return;
215
216
			Integer maxLength = recent.getInteger(XML.MAX_LENGTH);
217
			int max = RECENT_MAX_LENGTH;
218
			if(maxLength != null)
219
				max = maxLength.intValue();
220
221
			IMemento indices[] = recent.getChildren(XML.WORKSPACE);
222
			if(indices == null || indices.length <= 0)
223
				return;
224
225
			// if a user has edited maxLength to be shorter than the listed
226
			// indices, accept the list (its tougher for them to retype a long
227
			// list of paths than to update a max number)
228
			max = Math.max(max, indices.length);
229
230
			recentWorkspaces = new String[max];
231
			for(int i = 0; i < indices.length; ++i) {
232
				String path = indices[i].getString(XML.PATH);
233
				if(path == null)
234
					break;
235
				recentWorkspaces[i] = path; 
236
			}
237
			return;
238
		} catch (IOException e) {
239
			// do nothing -- cannot log because instance area has not been set
240
		} catch (WorkbenchException e) {
241
			// do nothing -- cannot log because instance area has not been set
242
		}
243
		finally {
244
			// create safe default if needed
245
			if(recentWorkspaces == null)
246
				recentWorkspaces = new String[RECENT_MAX_LENGTH];
247
		}
248
	}
249
250
	/**
251
	 * Return true if the protocol used to encode the argument memento is compatible
252
	 * with the receiver's implementation and false otherwise.
253
	 */
254
	private static boolean compatibleProtocol(IMemento memento) {
255
		IMemento protocolMemento = memento.getChild(XML.PROTOCOL);
256
		if(protocolMemento == null)
257
			return false;
258
259
		Integer version = protocolMemento.getInteger(XML.VERSION);
260
		return version != null && version.intValue() == PERS_ENCODING_VERSION;
261
	}
262
263
	/**
264
	 * The workspace data is stored in the well known file pointed to by the result
265
	 * of this method.
266
	 * @param create If the directory and file does not exist this parameter
267
	 *               controls whether it will be created.
268
	 * @return An url to the file and null if it does not exist or could not
269
	 *         be created.
270
	 */
271
	private static URL getPersistenceUrl(URL baseUrl, boolean create) {
272
		if(baseUrl == null)
273
			return null;
274
275
		try {
276
			// make sure the directory exists
277
			URL url = new URL(baseUrl, PERS_FOLDER);
278
			File dir = new File(url.getFile());
279
			if (!dir.exists() && (!create || !dir.mkdir()))
280
				return null;
281
282
			// make sure the file exists
283
			url = new URL(dir.toURL(), PERS_FILENAME);
284
			File persFile = new File(url.getFile());
285
			if (!persFile.exists() && (!create || !persFile.createNewFile()))
286
				return null;
287
288
			return persFile.toURL();
289
		} catch (IOException e) {
290
			// cannot log because instance area has not been set
291
			return null;
292
		}
293
	}
294
}
(-)src/org/eclipse/ui/internal/ide/ChooseWorkspaceDialog.java (+199 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.ide;
12
13
import java.net.MalformedURLException;
14
import java.net.URL;
15
16
import org.eclipse.core.runtime.Platform;
17
import org.eclipse.jface.dialogs.IDialogConstants;
18
import org.eclipse.jface.dialogs.TitleAreaDialog;
19
import org.eclipse.jface.resource.ImageDescriptor;
20
import org.eclipse.swt.SWT;
21
import org.eclipse.swt.events.ModifyEvent;
22
import org.eclipse.swt.events.ModifyListener;
23
import org.eclipse.swt.events.SelectionAdapter;
24
import org.eclipse.swt.events.SelectionEvent;
25
import org.eclipse.swt.graphics.Image;
26
import org.eclipse.swt.layout.GridData;
27
import org.eclipse.swt.layout.GridLayout;
28
import org.eclipse.swt.widgets.Button;
29
import org.eclipse.swt.widgets.Combo;
30
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.swt.widgets.DirectoryDialog;
33
import org.eclipse.swt.widgets.Label;
34
import org.eclipse.swt.widgets.Shell;
35
36
/**
37
 * A dialog that prompts for a directory to use as a workspace.
38
 */
39
public class ChooseWorkspaceDialog extends TitleAreaDialog {
40
	private ChooseWorkspaceData launchData;
41
	private String currentSelection;
42
43
	/**
44
	 * Create a modal dialog on the arugment shell, using and updating the argument
45
	 * data object.
46
	 */
47
	public ChooseWorkspaceDialog(Shell parentShell, ChooseWorkspaceData launchData) {
48
		super(parentShell);
49
		this.launchData = launchData;
50
	}
51
52
	/**
53
	 * Creates and returns the contents of the upper part of this dialog (above
54
	 * the button bar).
55
	 * <p>
56
	 * The <code>Dialog</code> implementation of this framework method creates
57
	 * and returns a new <code>Composite</code> with no margins and spacing.
58
	 * </p>
59
	 *
60
	 * @param the parent composite to contain the dialog area
61
	 * @return the dialog area control
62
	 */
63
	protected Control createDialogArea(Composite parent) {
64
		Composite composite = (Composite) super.createDialogArea(parent);
65
		setTitle(IDEWorkbenchMessages
66
				.getString("ChooseWorkspaceDialog.dialogTitle")); //$NON-NLS-1$
67
		setMessage(IDEWorkbenchMessages
68
				.getString("ChooseWorkspaceDialog.dialogMessage")); //$NON-NLS-1$
69
		setTitleImage();
70
71
		createWorkspaceBrowseRow(composite);
72
		return composite;
73
	}
74
75
	/**
76
	 * Configures the given shell in preparation for opening this window
77
	 * in it.
78
	 * <p>
79
	 * The default implementation of this framework method
80
	 * sets the shell's image and gives it a grid layout. 
81
	 * Subclasses may extend or reimplement.
82
	 * </p>
83
	 * 
84
	 * @param shell the shell
85
	 */
86
	protected void configureShell(Shell shell) {
87
		super.configureShell(shell);
88
		shell.setText(IDEWorkbenchMessages
89
				.getString("ChooseWorkspaceDialog.dialogName")); //$NON-NLS-1$
90
	}
91
92
	/**
93
	 * Notifies that the ok button of this dialog has been pressed.
94
	 * <p>
95
	 * The <code>Dialog</code> implementation of this framework method sets
96
	 * this dialog's return code to <code>Window.OK</code>
97
	 * and closes the dialog. Subclasses may override.
98
	 * </p>
99
	 */
100
	protected void okPressed() {
101
		launchData.workspaceSelected(currentSelection);
102
		super.okPressed();
103
	}
104
105
	/**
106
	 * Notifies that the cancel button of this dialog has been pressed.
107
	 * <p>
108
	 * The <code>Dialog</code> implementation of this framework method sets
109
	 * this dialog's return code to <code>Window.CANCEL</code>
110
	 * and closes the dialog. Subclasses may override if desired.
111
	 * </p>
112
	 */
113
	protected void cancelPressed() {
114
		currentSelection = null;
115
		launchData.workspaceSelected(currentSelection);
116
		super.cancelPressed();
117
	}
118
119
	private void setTitleImage() {
120
		try {
121
			URL installURL = Platform.getPlugin(
122
					IDEWorkbenchPlugin.IDE_WORKBENCH).getDescriptor()
123
					.getInstallURL();
124
			URL url = new URL(installURL, "icons/full/wizban/newfolder_wiz.gif");//$NON-NLS-1$
125
126
			ImageDescriptor desc = ImageDescriptor.createFromURL(url);
127
			Image image = desc.createImage();
128
			if (image != null)
129
				setTitleImage(image);
130
		} catch (MalformedURLException e) {
131
			// do nothing
132
		}
133
	}
134
135
	/**
136
	 * The main area of the dialog is just a row with the current selection
137
	 * information and a drop-down of the most recently used workspaces.
138
	 */
139
	private void createWorkspaceBrowseRow(Composite parent) {
140
		Composite panel = new Composite(parent, SWT.NONE);
141
142
		GridLayout layout = new GridLayout(3, false);
143
		layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
144
		layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
145
		layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
146
		layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
147
		panel.setLayout(layout);
148
		panel.setLayoutData(new GridData(GridData.FILL_BOTH));
149
		panel.setFont(parent.getFont());
150
151
		Label label = new Label(panel, SWT.NONE);
152
		label.setText(IDEWorkbenchMessages
153
				.getString("ChooseWorkspaceDialog.workspaceEntryLabel")); //$NON-NLS-1$
154
155
		final Combo text = new Combo(panel, SWT.BORDER | SWT.LEAD
156
				| SWT.DROP_DOWN);
157
		text.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
158
				| GridData.FILL_HORIZONTAL));
159
		setInitialTextValues(text);
160
		text.addModifyListener(new ModifyListener() {
161
			public void modifyText(ModifyEvent e) {
162
				currentSelection = text.getText();
163
			}
164
		});
165
166
		Button browseButton = new Button(panel, SWT.PUSH);
167
		browseButton.setText(IDEWorkbenchMessages
168
				.getString("ChooseWorkspaceDialog.browseLabel")); //$NON-NLS-1$
169
		setButtonLayoutData(browseButton);
170
		GridData data = (GridData) browseButton.getLayoutData();
171
		data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_END;
172
		browseButton.setLayoutData(data);
173
		browseButton.addSelectionListener(new SelectionAdapter() {
174
			public void widgetSelected(SelectionEvent e) {
175
				DirectoryDialog dialog = new DirectoryDialog(getShell());
176
				dialog.setText(IDEWorkbenchMessages
177
								.getString("ChooseWorkspaceDialog.directoryBrowserTitle")); //$NON-NLS-1$
178
				dialog.setMessage(IDEWorkbenchMessages
179
								.getString("ChooseWorkspaceDialog.directoryBrowserMessage")); //$NON-NLS-1$
180
				dialog.setFilterPath(currentSelection);
181
				String dir = dialog.open();
182
				if (dir != null)
183
					text.setText(dir);
184
			}
185
		});
186
	}
187
188
	private void setInitialTextValues(Combo text) {
189
		String[] recentWorkspaces = launchData.getRecentWorkspaces();
190
		for(int i = 0; i < recentWorkspaces.length; ++i)
191
			if(recentWorkspaces[i] != null)
192
				text.add(recentWorkspaces[i]);
193
194
		currentSelection = text.getItemCount() > 0
195
				? text.getItem(0)
196
				: launchData.getInitialDefault();
197
		text.setText(currentSelection);
198
	}
199
}

Return to bug 32147