Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 74480 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (+7 lines)
Lines 1452-1457 Link Here
1452
            </or>
1452
            </or>
1453
         </enabledWhen>
1453
         </enabledWhen>
1454
      </page>
1454
      </page>
1455
      <page
1456
            adaptable="true"
1457
            class="org.eclipse.debug.internal.ui.launchConfigurations.properties.ExecutionPropertiesPage"
1458
            id="org.eclipse.debug.ui.properties.execution"
1459
            name="Execution"
1460
            objectClass="org.eclipse.core.resources.IResource">
1461
      </page>
1455
   </extension>
1462
   </extension>
1456
<!-- commands and their bindings
1463
<!-- commands and their bindings
1457
NOTE: 
1464
NOTE: 
(-)ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java (+1 lines)
Lines 105-110 Link Here
105
	// Property pages
105
	// Property pages
106
	public static final String PROCESS_PROPERTY_PAGE = PREFIX + "process_property_page_context"; //$NON-NLS-1$
106
	public static final String PROCESS_PROPERTY_PAGE = PREFIX + "process_property_page_context"; //$NON-NLS-1$
107
	public static final String PROCESS_PAGE_RUN_AT = PREFIX + "process_page_run_at_time_widget"; //$NON-NLS-1$
107
	public static final String PROCESS_PAGE_RUN_AT = PREFIX + "process_page_run_at_time_widget"; //$NON-NLS-1$
108
	public static final String EXECUTION_PROPERTY_PAGE = PREFIX + "execution_property_page"; //$NON-NLS-1$
108
	
109
	
109
	// Launch configuration dialog pages
110
	// Launch configuration dialog pages
110
	public static final String LAUNCH_CONFIGURATION_DIALOG_COMMON_TAB = PREFIX + "launch_configuration_dialog_common_tab"; //$NON-NLS-1$
111
	public static final String LAUNCH_CONFIGURATION_DIALOG_COMMON_TAB = PREFIX + "launch_configuration_dialog_common_tab"; //$NON-NLS-1$
(-)ui/org/eclipse/debug/internal/ui/launchConfigurations/properties/CategoryFilter.java (+39 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui.launchConfigurations.properties;
12
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.debug.core.ILaunchConfiguration;
15
import org.eclipse.jface.viewers.Viewer;
16
import org.eclipse.jface.viewers.ViewerFilter;
17
18
/**
19
 * Filters configurations in non-default launch categories.
20
 *
21
 * @since 3.3
22
 */
23
public class CategoryFilter extends ViewerFilter {
24
25
	/* (non-Javadoc)
26
	 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
27
	 */
28
	public boolean select(Viewer viewer, Object parentElement, Object element) {
29
		if (element instanceof ILaunchConfiguration) {
30
			try {
31
				return ((ILaunchConfiguration)element).getType().getCategory() == null;
32
			} catch (CoreException e) {
33
				return false;
34
			}
35
		}
36
		return true;
37
	}
38
39
}
(-)ui/org/eclipse/debug/internal/ui/launchConfigurations/properties/LaunchConfigurationComparator.java (+78 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui.launchConfigurations.properties;
12
13
import java.util.ArrayList;
14
import java.util.Collections;
15
import java.util.Comparator;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Map;
20
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.debug.core.DebugPlugin;
23
import org.eclipse.debug.core.ILaunchConfiguration;
24
import org.eclipse.debug.core.ILaunchConfigurationType;
25
import org.eclipse.ui.model.WorkbenchViewerComparator;
26
27
/**
28
 * Groups configurations by type.
29
 * 
30
 * @since 3.3
31
 */
32
public class LaunchConfigurationComparator extends WorkbenchViewerComparator {
33
34
	private static Map categories;
35
	
36
	public int category(Object element) {
37
		Map map = getCategories();
38
		if (element instanceof ILaunchConfiguration) {
39
			ILaunchConfiguration configuration = (ILaunchConfiguration) element;
40
			try {
41
				Integer i = (Integer) map.get(configuration.getType());
42
				if (i != null) {
43
					return i.intValue();
44
				}
45
			} catch (CoreException e) {
46
			}
47
		}
48
		return map.size();
49
	}
50
	
51
	private Map getCategories() {
52
		if (categories == null) {
53
			categories = new HashMap();
54
			ILaunchConfigurationType[] lcts = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationTypes();
55
			List types = new ArrayList(lcts.length);
56
			for (int i = 0; i < lcts.length; i++) {
57
				types.add(lcts[i]);
58
			}
59
			Collections.sort(types, new Comparator() {
60
				public int compare(Object o1, Object o2) {
61
					ILaunchConfigurationType t1 = (ILaunchConfigurationType) o1;
62
					ILaunchConfigurationType t2 = (ILaunchConfigurationType) o2;
63
					return t1.getName().compareTo(t2.getName());
64
				}
65
			
66
			});
67
			Iterator iterator = types.iterator();
68
			int i = 0;
69
			while (iterator.hasNext()) {
70
				categories.put(iterator.next(), new Integer(i));
71
				i++;
72
			}
73
		}
74
		return categories;
75
	}
76
77
	
78
}
(-)ui/org/eclipse/debug/internal/ui/launchConfigurations/properties/ExecutionPropertiesPage.java (+449 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui.launchConfigurations.properties;
12
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Collections;
16
import java.util.Comparator;
17
import java.util.Iterator;
18
import java.util.List;
19
20
import org.eclipse.core.resources.IResource;
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IAdaptable;
23
import org.eclipse.core.runtime.IPath;
24
import org.eclipse.debug.core.DebugPlugin;
25
import org.eclipse.debug.core.ILaunchConfiguration;
26
import org.eclipse.debug.core.ILaunchConfigurationType;
27
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
28
import org.eclipse.debug.core.ILaunchManager;
29
import org.eclipse.debug.internal.ui.DebugUIPlugin;
30
import org.eclipse.debug.internal.ui.DefaultLabelProvider;
31
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
32
import org.eclipse.debug.internal.ui.SWTUtil;
33
import org.eclipse.debug.ui.DebugUITools;
34
import org.eclipse.debug.ui.ILaunchGroup;
35
import org.eclipse.jface.viewers.ArrayContentProvider;
36
import org.eclipse.jface.viewers.CheckStateChangedEvent;
37
import org.eclipse.jface.viewers.CheckboxTableViewer;
38
import org.eclipse.jface.viewers.ICheckStateListener;
39
import org.eclipse.jface.viewers.ISelection;
40
import org.eclipse.jface.viewers.ISelectionChangedListener;
41
import org.eclipse.jface.viewers.IStructuredSelection;
42
import org.eclipse.jface.viewers.SelectionChangedEvent;
43
import org.eclipse.jface.viewers.StructuredSelection;
44
import org.eclipse.jface.window.Window;
45
import org.eclipse.swt.SWT;
46
import org.eclipse.swt.events.SelectionEvent;
47
import org.eclipse.swt.events.SelectionListener;
48
import org.eclipse.swt.layout.GridData;
49
import org.eclipse.swt.layout.GridLayout;
50
import org.eclipse.swt.widgets.Button;
51
import org.eclipse.swt.widgets.Composite;
52
import org.eclipse.swt.widgets.Control;
53
import org.eclipse.swt.widgets.Table;
54
import org.eclipse.ui.PlatformUI;
55
import org.eclipse.ui.dialogs.ListDialog;
56
import org.eclipse.ui.dialogs.PropertyPage;
57
58
import com.ibm.icu.text.MessageFormat;
59
60
/**
61
 * Displays execution settings for a resource - associated launch configurations.
62
 * 
63
 * @since 3.3
64
 */
65
public class ExecutionPropertiesPage extends PropertyPage implements ICheckStateListener, ISelectionChangedListener, SelectionListener {
66
	
67
	private CheckboxTableViewer viewer;
68
	private Button newButton;
69
	private Button copyButton;
70
	private Button editButton;
71
	private Button deleteButton;
72
	
73
	/**
74
	 * List of configurations to be deleted
75
	 */
76
	private List deletedConfigurations = new ArrayList();
77
	
78
	/**
79
	 * List of original default candidates for the resource
80
	 */
81
	private List originalCandidates;
82
	
83
	/* (non-Javadoc)
84
	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
85
	 */
86
	protected Control createContents(Composite parent) {
87
		// TODO: add help to documentation
88
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IDebugHelpContextIds.EXECUTION_PROPERTY_PAGE);
89
		
90
		Composite composite = new Composite(parent, SWT.NONE);
91
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
92
		GridLayout layout = new GridLayout();
93
		layout.marginHeight = 0;
94
		layout.marginWidth = 0;
95
		composite.setLayout(layout);
96
		
97
		SWTUtil.createLabel(composite, MessageFormat.format("&Select default launch settings for {0}:", new String[]{getResource().getName()}), 2);
98
		
99
		Composite tableAndButtons = new Composite(composite, SWT.NONE);
100
		tableAndButtons.setLayoutData(new GridData(GridData.FILL_BOTH));
101
		layout = new GridLayout();
102
		layout.marginHeight = 0;
103
		layout.marginWidth = 0;
104
		layout.numColumns = 2;
105
		tableAndButtons.setLayout(layout);
106
		
107
		viewer= CheckboxTableViewer.newCheckList(tableAndButtons, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
108
		viewer.setLabelProvider(new DefaultLabelProvider());
109
		viewer.setContentProvider(new ArrayContentProvider());
110
		viewer.setComparator(new LaunchConfigurationComparator());
111
		viewer.addCheckStateListener(this);
112
		// Only filter private configurations and external tools to avoid filtering a default
113
		viewer.addFilter(new PrivateConfigurationFilter());
114
		viewer.addFilter(new CategoryFilter());
115
		Table builderTable= viewer.getTable();
116
		GridData gridData = new GridData(GridData.FILL_BOTH);
117
		gridData.heightHint = 300;
118
		builderTable.setLayoutData(gridData);
119
		
120
		IResource resource = getResource();
121
		originalCandidates = getDefaultCandidates(resource);
122
		viewer.setInput(originalCandidates);
123
		try {
124
			ILaunchConfiguration configuration = DebugPlugin.getDefault().getLaunchManager().getDefaultConfiguration(resource);
125
			if (configuration != null) {
126
				Iterator iterator = originalCandidates.iterator();
127
				while (iterator.hasNext()) {
128
					ILaunchConfigurationWorkingCopy wc = (ILaunchConfigurationWorkingCopy) iterator.next();
129
					if (configuration.equals(wc.getOriginal())) {
130
						viewer.setChecked(wc, true);
131
						break;
132
					}
133
				}
134
			}
135
		} catch (CoreException e) {
136
			setErrorMessage(e.getMessage());
137
		}
138
		
139
		Composite buttonArea = new Composite(tableAndButtons, SWT.NONE);
140
		layout = new GridLayout();
141
		layout.marginHeight = 0;
142
		layout.marginWidth = 0;
143
		buttonArea.setLayout(layout);
144
		buttonArea.setLayoutData(new GridData(GridData.FILL_VERTICAL));
145
		newButton = SWTUtil.createPushButton(buttonArea, "New...", null);
146
		newButton.addSelectionListener(this);
147
		copyButton = SWTUtil.createPushButton(buttonArea, "Copy...", null);
148
		copyButton.addSelectionListener(this);
149
		editButton = SWTUtil.createPushButton(buttonArea, "Edit...", null);
150
		editButton.addSelectionListener(this);
151
		deleteButton = SWTUtil.createPushButton(buttonArea, "Delete", null);
152
		deleteButton.addSelectionListener(this);
153
		
154
		viewer.addSelectionChangedListener(this);
155
		applyDialogFont(composite);
156
		updateButtons(new StructuredSelection());
157
		return composite;
158
	}
159
160
	/**
161
	 * Returns the resource this property page is open on.
162
	 * 
163
	 * @return resource
164
	 */
165
	protected IResource getResource() {
166
		Object element = getElement();
167
		IResource resource = null;
168
		if (element instanceof IResource) {
169
			resource = (IResource) element;
170
		} else if (element instanceof IAdaptable) {
171
			resource = (IResource) ((IAdaptable)element).getAdapter(IResource.class);
172
		}
173
		return resource;
174
	}
175
176
	/* (non-Javadoc)
177
	 * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
178
	 */
179
	public void checkStateChanged(CheckStateChangedEvent event) {
180
		ILaunchConfiguration configuration = (ILaunchConfiguration) event.getElement();
181
		// only allow one check
182
		viewer.setCheckedElements(new Object[]{configuration});
183
		// validate
184
		if (!configuration.isLocal()) {
185
			if (!getResource().getProject().equals(configuration.getFile().getProject())) {
186
				// a config must be stored in the same project that it is a default config for
187
				setErrorMessage(MessageFormat.format("Configuration must be located in project {0}", new String[]{getResource().getProject().getName()}));
188
				setValid(false);
189
				return;
190
			}
191
		}
192
		setErrorMessage(null);
193
		setValid(true);
194
	}
195
196
	/* (non-Javadoc)
197
	 * @see org.eclipse.jface.preference.PreferencePage#performOk()
198
	 */
199
	public boolean performOk() {
200
		Object[] checked = viewer.getCheckedElements();
201
		try {
202
			ILaunchConfiguration def = null;
203
			if (checked.length == 1) {
204
					def = (ILaunchConfiguration) checked[0];
205
			}
206
			DebugPlugin.getDefault().getLaunchManager().setDefaultConfiguration(getResource(), def);
207
		} catch (CoreException e) {
208
			setErrorMessage(e.getMessage());
209
			return false;
210
		}
211
		return super.performOk();
212
	}
213
214
	/* (non-Javadoc)
215
	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
216
	 */
217
	protected void performDefaults() {
218
		viewer.setAllChecked(false);
219
		setErrorMessage(null);
220
		setValid(true);
221
		super.performDefaults();
222
	}
223
224
	/* (non-Javadoc)
225
	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
226
	 */
227
	public void selectionChanged(SelectionChangedEvent event) {
228
		ISelection s = event.getSelection();
229
		if (s instanceof IStructuredSelection) {
230
			updateButtons((IStructuredSelection) s);
231
		}
232
		
233
	}
234
235
	/**
236
	 * Update buttons based on the given selection.
237
	 * 
238
	 * @param selection
239
	 */
240
	private void updateButtons(IStructuredSelection selection) {
241
		if (selection.size() == 0) {
242
			editButton.setEnabled(false);
243
			copyButton.setEnabled(false);
244
			deleteButton.setEnabled(false);
245
		} else if (selection.size() == 1) {
246
			editButton.setEnabled(true);
247
			copyButton.setEnabled(true);
248
			deleteButton.setEnabled(true);
249
		} else {
250
			editButton.setEnabled(false);
251
			copyButton.setEnabled(false);
252
			deleteButton.setEnabled(true);
253
		}
254
	}
255
256
	/**
257
	 * Returns a list of potential default configurations candidates for the given
258
	 * resource. The configurations are working copies.
259
	 *  
260
	 * @param resource resource
261
	 * @return list of default candidates
262
	 */
263
	private List getDefaultCandidates(IResource resource) {
264
		IPath resourcePath = resource.getFullPath();
265
		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
266
		List list = new ArrayList();
267
		try {
268
			ILaunchConfiguration[] configurations = manager.getLaunchConfigurations();
269
			for (int i = 0; i < configurations.length; i++) {
270
				ILaunchConfiguration configuration = configurations[i];
271
				IResource[] resources = configuration.getMappedResources();
272
				if (resources != null) {
273
					for (int j = 0; j < resources.length; j++) {
274
						IResource mappedResource = resources[j];
275
						if (resource.equals(mappedResource) || 
276
								resourcePath.isPrefixOf(mappedResource.getFullPath())) {
277
							list.add(configuration.getWorkingCopy());
278
							break;
279
						}
280
					}
281
				} else {
282
					// 1. similar to launch dialog - if no resource mapping, display the config
283
					// 2. only consider the default launch category (applications, *not* external tools)
284
					if (configuration.getType().getCategory() == null) {
285
						list.add(configuration.getWorkingCopy());
286
					}
287
				}
288
			}
289
		} catch (CoreException e) {
290
			list.clear();
291
			DebugUIPlugin.log(e);
292
		}
293
		return list;
294
	}
295
296
	/* (non-Javadoc)
297
	 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
298
	 */
299
	public void widgetDefaultSelected(SelectionEvent e) {
300
	}
301
302
	/* (non-Javadoc)
303
	 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
304
	 */
305
	public void widgetSelected(SelectionEvent e) {
306
		if (e.widget == newButton) {
307
			handleNew();
308
		} else if (e.widget == copyButton) {
309
			handleCopy();
310
		} else if (e.widget == deleteButton) {
311
			handleDelete();
312
		} else if (e.widget == editButton) {
313
			handleEdit();
314
		}
315
	}
316
	
317
	/**
318
	 * Returns selected configurations.
319
	 * 
320
	 * @return selected configurations
321
	 */
322
	private ILaunchConfigurationWorkingCopy[] getSelectedConfigurations() {
323
		Object[] array = ((IStructuredSelection)viewer.getSelection()).toArray();
324
		ILaunchConfigurationWorkingCopy[] lcs = new ILaunchConfigurationWorkingCopy[array.length];
325
		System.arraycopy(array, 0, lcs, 0, array.length);
326
		return lcs;
327
	}
328
329
	/**
330
	 * Copy the selection
331
	 */
332
	private void handleCopy() {
333
		ILaunchConfigurationWorkingCopy configuration = getSelectedConfigurations()[0];
334
		try {
335
			ILaunchConfigurationWorkingCopy copy = configuration.copy(
336
					DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom(configuration.getName()));
337
			copy.setAttributes(configuration.getAttributes());
338
			int code = edit(copy);
339
			if (code == Window.OK) {
340
				originalCandidates.add(copy);
341
				viewer.refresh();
342
				viewer.setSelection(new StructuredSelection(copy));
343
			}
344
		} catch (CoreException e) {
345
			setErrorMessage(e.getMessage());
346
		}
347
	}
348
349
	/**
350
	 * Delete the selection
351
	 */
352
	private void handleDelete() {
353
		Table table = viewer.getTable();
354
		int[] indices = table.getSelectionIndices();
355
		Arrays.sort(indices);
356
		ILaunchConfiguration[] configurations = getSelectedConfigurations();
357
		for (int i = 0; i < configurations.length; i++) {
358
			deletedConfigurations.add(configurations[i]);
359
			originalCandidates.remove(configurations[i]);
360
		}
361
		viewer.refresh();
362
		if (indices[0] < table.getItemCount()) {
363
			viewer.setSelection(new StructuredSelection(table.getItem(indices[0]).getData()));
364
		} else if (table.getItemCount() > 0) {
365
			viewer.setSelection(new StructuredSelection(table.getItem(table.getItemCount() - 1).getData()));
366
		}
367
	}
368
369
	/**
370
	 * Edit the selection
371
	 */
372
	private void handleEdit() {
373
		edit(getSelectedConfigurations()[0]);
374
		viewer.refresh();
375
	}
376
377
	/**
378
	 * Edits the given configuration as a nested working copy.
379
	 * Returns the code from the dialog used to edit the configuration.
380
	 * 
381
	 * @param configuration
382
	 * @return dialog return code - OK or CANCEL
383
	 */
384
	private int edit(ILaunchConfigurationWorkingCopy configuration) {
385
		try {
386
			ILaunchConfigurationWorkingCopy copy = configuration.getNestedWorkingCopy();
387
			ILaunchGroup group = DebugUITools.getLaunchGroup(configuration, ILaunchManager.RUN_MODE);
388
			if (group == null) {
389
				group = DebugUITools.getLaunchGroup(configuration, ILaunchManager.DEBUG_MODE);
390
			}
391
			int code = DebugUITools.openLaunchConfigurationPropertiesDialog(getShell(), copy, group.getIdentifier());
392
			if (code == Window.OK) {
393
				copy.doSave();
394
			}
395
			return code;
396
		} catch (CoreException e) {
397
			setErrorMessage(e.getMessage());
398
		}
399
		return Window.CANCEL;
400
	}
401
402
	/**
403
	 * Create a new configuration
404
	 */
405
	private void handleNew() {
406
		ILaunchConfigurationType[] types = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationTypes();
407
		List avail = new ArrayList(types.length); 
408
		for (int i = 0; i < types.length; i++) {
409
			ILaunchConfigurationType type = types[i];
410
			if (type.getCategory() == null) {
411
				// TODO: external tools?
412
				avail.add(type);
413
			}
414
		}
415
		Collections.sort(avail, new Comparator() {
416
				public int compare(Object o1, Object o2) {
417
					ILaunchConfigurationType t1 = (ILaunchConfigurationType) o1;
418
					ILaunchConfigurationType t2 = (ILaunchConfigurationType) o2;
419
					return t1.getName().compareTo(t2.getName());
420
				}
421
			
422
			});
423
		ListDialog dialog = new ListDialog(getShell());
424
		dialog.setTitle("Selection Configuration Type");
425
		dialog.setContentProvider(new ArrayContentProvider());
426
		dialog.setLabelProvider(new DefaultLabelProvider());
427
		dialog.setAddCancelButton(true);
428
		dialog.setMessage("&Select the kind of configuration to create:");
429
		dialog.setInput(avail);
430
		if (dialog.open() == Window.OK) {
431
			Object[] result = dialog.getResult();
432
			if (result.length == 1) {
433
				ILaunchConfigurationType type = (ILaunchConfigurationType) result[0];
434
				try {
435
					ILaunchConfigurationWorkingCopy wc = type.newInstance(null, DebugPlugin.getDefault().getLaunchManager().
436
							generateUniqueLaunchConfigurationNameFrom("New Configuration"));
437
					if (edit(wc) == Window.OK) {
438
						originalCandidates.add(wc);
439
						viewer.refresh();
440
						viewer.setSelection(new StructuredSelection(wc));
441
					}
442
				} catch (CoreException e) {
443
					setErrorMessage(e.getMessage());
444
				}
445
			}
446
		}
447
	}
448
	
449
}
(-)ui/org/eclipse/debug/internal/ui/launchConfigurations/properties/PrivateConfigurationFilter.java (+35 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui.launchConfigurations.properties;
12
13
import org.eclipse.debug.core.ILaunchConfiguration;
14
import org.eclipse.debug.ui.DebugUITools;
15
import org.eclipse.jface.viewers.Viewer;
16
import org.eclipse.jface.viewers.ViewerFilter;
17
18
/**
19
 * Filters private configurations.
20
 *
21
 * @since 3.3
22
 */
23
public class PrivateConfigurationFilter extends ViewerFilter {
24
25
	/* (non-Javadoc)
26
	 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
27
	 */
28
	public boolean select(Viewer viewer, Object parentElement, Object element) {
29
		if (element instanceof ILaunchConfiguration) {
30
			return !DebugUITools.isPrivate((ILaunchConfiguration) element);
31
		}
32
		return true;
33
	}
34
35
}
(-)core/org/eclipse/debug/internal/core/LaunchManager.java (-1 / +106 lines)
Lines 57-62 Link Here
57
import org.eclipse.core.resources.IResourceDeltaVisitor;
57
import org.eclipse.core.resources.IResourceDeltaVisitor;
58
import org.eclipse.core.resources.IResourceProxy;
58
import org.eclipse.core.resources.IResourceProxy;
59
import org.eclipse.core.resources.IResourceProxyVisitor;
59
import org.eclipse.core.resources.IResourceProxyVisitor;
60
import org.eclipse.core.resources.ProjectScope;
60
import org.eclipse.core.resources.ResourcesPlugin;
61
import org.eclipse.core.resources.ResourcesPlugin;
61
import org.eclipse.core.runtime.CoreException;
62
import org.eclipse.core.runtime.CoreException;
62
import org.eclipse.core.runtime.IConfigurationElement;
63
import org.eclipse.core.runtime.IConfigurationElement;
Lines 65-75 Link Here
65
import org.eclipse.core.runtime.ISafeRunnable;
66
import org.eclipse.core.runtime.ISafeRunnable;
66
import org.eclipse.core.runtime.IStatus;
67
import org.eclipse.core.runtime.IStatus;
67
import org.eclipse.core.runtime.ListenerList;
68
import org.eclipse.core.runtime.ListenerList;
69
import org.eclipse.core.runtime.Path;
68
import org.eclipse.core.runtime.Platform;
70
import org.eclipse.core.runtime.Platform;
69
import org.eclipse.core.runtime.PlatformObject;
71
import org.eclipse.core.runtime.PlatformObject;
70
import org.eclipse.core.runtime.Preferences;
72
import org.eclipse.core.runtime.Preferences;
71
import org.eclipse.core.runtime.SafeRunner;
73
import org.eclipse.core.runtime.SafeRunner;
72
import org.eclipse.core.runtime.Status;
74
import org.eclipse.core.runtime.Status;
75
import org.eclipse.core.runtime.preferences.InstanceScope;
73
import org.eclipse.core.variables.VariablesPlugin;
76
import org.eclipse.core.variables.VariablesPlugin;
74
import org.eclipse.debug.core.DebugException;
77
import org.eclipse.debug.core.DebugException;
75
import org.eclipse.debug.core.DebugPlugin;
78
import org.eclipse.debug.core.DebugPlugin;
Lines 77-82 Link Here
77
import org.eclipse.debug.core.ILaunchConfiguration;
80
import org.eclipse.debug.core.ILaunchConfiguration;
78
import org.eclipse.debug.core.ILaunchConfigurationListener;
81
import org.eclipse.debug.core.ILaunchConfigurationListener;
79
import org.eclipse.debug.core.ILaunchConfigurationType;
82
import org.eclipse.debug.core.ILaunchConfigurationType;
83
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
80
import org.eclipse.debug.core.ILaunchDelegate;
84
import org.eclipse.debug.core.ILaunchDelegate;
81
import org.eclipse.debug.core.ILaunchListener;
85
import org.eclipse.debug.core.ILaunchListener;
82
import org.eclipse.debug.core.ILaunchManager;
86
import org.eclipse.debug.core.ILaunchManager;
Lines 94-99 Link Here
94
import org.eclipse.debug.internal.core.sourcelookup.SourceContainerType;
98
import org.eclipse.debug.internal.core.sourcelookup.SourceContainerType;
95
import org.eclipse.debug.internal.core.sourcelookup.SourcePathComputer;
99
import org.eclipse.debug.internal.core.sourcelookup.SourcePathComputer;
96
import org.eclipse.osgi.service.environment.Constants;
100
import org.eclipse.osgi.service.environment.Constants;
101
import org.osgi.service.prefs.BackingStoreException;
97
import org.w3c.dom.Document;
102
import org.w3c.dom.Document;
98
import org.w3c.dom.Element;
103
import org.w3c.dom.Element;
99
import org.w3c.dom.Node;
104
import org.w3c.dom.Node;
Lines 116-121 Link Here
116
	
121
	
117
	
122
	
118
	/**
123
	/**
124
	 * 
125
	 */
126
	private static final String DEFAULT_CONFIGURATION = "defaultConfiguration";
127
	/**
119
	 * Constants for xml node names
128
	 * Constants for xml node names
120
	 * 
129
	 * 
121
	 * @since 3.3
130
	 * @since 3.3
Lines 2312-2316 Link Here
2312
            }
2321
            }
2313
        }
2322
        }
2314
        return title;
2323
        return title;
2315
    }	
2324
    }
2325
2326
	/* (non-Javadoc)
2327
	 * @see org.eclipse.debug.core.ILaunchManager#getDefaultConfiguration(org.eclipse.core.resources.IResource)
2328
	 */
2329
	public ILaunchConfiguration getDefaultConfiguration(IResource resource) throws CoreException {
2330
		IProject project = resource.getProject();
2331
		if (project != null) {
2332
			org.osgi.service.prefs.Preferences projectNode = getProjectNode(resource);
2333
			String configValue = projectNode.get(DEFAULT_CONFIGURATION, null);
2334
			if (configValue != null) {
2335
				// shared config
2336
				IFile file = project.getFile(Path.fromPortableString(configValue));
2337
				return getLaunchConfiguration(file);
2338
			} else {
2339
				org.osgi.service.prefs.Preferences instanceNode = getInstanceNode(resource);
2340
				configValue = instanceNode.get(DEFAULT_CONFIGURATION, null);
2341
				if (configValue != null) {
2342
					// local config
2343
					return getLaunchConfiguration(configValue);
2344
				}
2345
			}
2346
		}
2347
		return null;
2348
	}
2349
2350
	/* (non-Javadoc)
2351
	 * @see org.eclipse.debug.core.ILaunchManager#setDefaultConfiguration(org.eclipse.core.resources.IResource, org.eclipse.debug.core.ILaunchConfiguration)
2352
	 */
2353
	public void setDefaultConfiguration(IResource resource, ILaunchConfiguration configuration) throws CoreException {
2354
		IProject project = resource.getProject();
2355
		if (project == null) {
2356
			throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
2357
					DebugPlugin.INTERNAL_ERROR, "Illegal argument: can only set default launch configuration on and within projects.", null));
2358
		}
2359
		if (configuration != null && !configuration.isLocal()) {
2360
			if (!configuration.getFile().getProject().equals(project)) {
2361
				throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
2362
						DebugPlugin.INTERNAL_ERROR, "A shared launch configuration must be shared in same project that it is a default configuration for.", null));
2363
			}
2364
		}
2365
		
2366
		// remove previous settings, if any
2367
		org.osgi.service.prefs.Preferences projectNode = getProjectNode(resource);
2368
		projectNode.remove(DEFAULT_CONFIGURATION);
2369
		flush(projectNode);
2370
		org.osgi.service.prefs.Preferences instanceNode = getInstanceNode(resource);
2371
		instanceNode.remove(DEFAULT_CONFIGURATION);
2372
		flush(instanceNode);
2373
		
2374
		if (configuration != null) {
2375
			org.osgi.service.prefs.Preferences node = null;
2376
			String configurationValue = null;
2377
			if (configuration.isLocal()) {
2378
				// for local configurations, use workspace (instance) scope preferences
2379
				node = instanceNode;
2380
				if (configuration.isWorkingCopy()) {
2381
					configurationValue = ((ILaunchConfigurationWorkingCopy)configuration).getOriginal().getMemento();
2382
				} else {
2383
					configurationValue = configuration.getMemento();
2384
				}
2385
			} else {
2386
				// for shared configurations, use project scope preferences
2387
				node = projectNode;
2388
				configurationValue = configuration.getFile().getProjectRelativePath().toPortableString();
2389
			}
2390
			node.put(DEFAULT_CONFIGURATION, configurationValue);
2391
			flush(node);
2392
		}
2393
		
2394
	}	
2395
	
2396
	private void flush(org.osgi.service.prefs.Preferences node) {
2397
		try {
2398
			node.flush();
2399
		} catch (BackingStoreException e) {
2400
			// TODO Auto-generated catch block
2401
			e.printStackTrace();
2402
		}
2403
	}
2404
	
2405
	private org.osgi.service.prefs.Preferences getProjectNode(IResource resource) {
2406
		org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode();
2407
		ProjectScope scope = new ProjectScope(resource.getProject());
2408
		node = scope.getNode(DebugPlugin.getUniqueIdentifier());
2409
		IProject project = resource.getProject();
2410
		if (!resource.equals(project)) {
2411
			node = node.node(resource.getProjectRelativePath().toString());
2412
		}
2413
		return node;
2414
	}
2415
	
2416
	private org.osgi.service.prefs.Preferences getInstanceNode(IResource resource) {
2417
		org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode();
2418
		node = node.node(InstanceScope.SCOPE).node(DebugPlugin.getUniqueIdentifier());
2419
		return node.node(resource.getFullPath().makeRelative().toString());
2420
	}
2316
}
2421
}
(-)core/org/eclipse/debug/internal/core/LaunchConfigurationWorkingCopy.java (-25 / +81 lines)
Lines 86-91 Link Here
86
	private IContainer fContainer;
86
	private IContainer fContainer;
87
	
87
	
88
	/**
88
	/**
89
	 * Parent working copy.
90
	 * @since 3.3
91
	 */
92
	private LaunchConfigurationWorkingCopy fParent = null;
93
	
94
	/**
89
	 * Constructs a working copy of the specified launch 
95
	 * Constructs a working copy of the specified launch 
90
	 * configuration.
96
	 * configuration.
91
	 * 
97
	 * 
Lines 103-108 Link Here
103
	}
109
	}
104
	
110
	
105
	/**
111
	/**
112
	 * Constructs a working copy of the specified launch configuration as its parent.
113
	 * 
114
	 * @param parent launch configuration to make
115
	 *  a working copy of
116
	 * @exception CoreException if unable to initialize this
117
	 *  working copy's attributes based on the original configuration
118
	 */
119
	protected LaunchConfigurationWorkingCopy(LaunchConfigurationWorkingCopy parent) throws CoreException {
120
		super(parent.getLocation());
121
		setName(parent.getName());
122
		copyFrom(parent);
123
		setOriginal((LaunchConfiguration) parent.getOriginal());
124
		fParent = parent;
125
		fSuppressChange = false;
126
	}	
127
	
128
	/**
106
	 * Constructs a copy of the specified launch 
129
	 * Constructs a copy of the specified launch 
107
	 * configuration, with the given (new) name.
130
	 * configuration, with the given (new) name.
108
	 * 
131
	 * 
Lines 149-183 Link Here
149
	 * @see ILaunchConfigurationWorkingCopy#doSave()
172
	 * @see ILaunchConfigurationWorkingCopy#doSave()
150
	 */
173
	 */
151
	public synchronized ILaunchConfiguration doSave() throws CoreException {
174
	public synchronized ILaunchConfiguration doSave() throws CoreException {
152
		if (isDirty()) {
175
		if (fParent == null) {
153
			boolean useRunnable= true;
176
			if (isDirty()) {
154
			if (isLocal()) {
177
				boolean useRunnable= true;
155
				if (isMoved()) {
178
				if (isLocal()) {
156
					// If this config was moved from a shared location, saving
179
					if (isMoved()) {
157
					// it will delete the original from the workspace. Use runnable.
180
						// If this config was moved from a shared location, saving
158
					useRunnable= !isNew() && !getOriginal().isLocal();
181
						// it will delete the original from the workspace. Use runnable.
182
						useRunnable= !isNew() && !getOriginal().isLocal();
183
					} else {
184
						useRunnable= false;
185
					}
186
				}
187
	
188
				if (useRunnable) {
189
					IWorkspaceRunnable wr = new IWorkspaceRunnable() {
190
						public void run(IProgressMonitor pm) throws CoreException {
191
							doSave0();
192
						}
193
					};
194
					
195
					ResourcesPlugin.getWorkspace().run(wr, null, 0, null);
159
				} else {
196
				} else {
160
					useRunnable= false;
197
					//file is persisted in the metadata not the workspace
198
					doSave0();
161
				}
199
				}
200
	
201
				getLaunchManager().setMovedFromTo(null, null);
162
			}
202
			}
163
203
	
164
			if (useRunnable) {
204
			return new LaunchConfiguration(getLocation());
165
				IWorkspaceRunnable wr = new IWorkspaceRunnable() {
205
		} else {
166
					public void run(IProgressMonitor pm) throws CoreException {
206
			// save to parent working copy
167
						doSave0();
207
			fParent.setName(getName());
168
					}
208
			fParent.copyFrom(this);
169
				};
209
			return fParent;
170
				
171
				ResourcesPlugin.getWorkspace().run(wr, null, 0, null);
172
			} else {
173
				//file is persisted in the metadata not the workspace
174
				doSave0();
175
			}
176
177
			getLaunchManager().setMovedFromTo(null, null);
178
		}
210
		}
179
180
		return new LaunchConfiguration(getLocation());
181
	}
211
	}
182
212
183
	
213
	
Lines 610-615 Link Here
610
		setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_PATHS, paths);
640
		setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_PATHS, paths);
611
		setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_TYPES, types);
641
		setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_TYPES, types);
612
	}
642
	}
643
	
644
	/* (non-Javadoc)
645
	 * @see org.eclipse.debug.internal.core.LaunchConfiguration#getWorkingCopy()
646
	 */
647
	public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException {
648
		if (fParent == null) {
649
			return super.getWorkingCopy();
650
		} else {
651
			return getNestedWorkingCopy();
652
		}
653
	}
654
655
	/* (non-Javadoc)
656
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getNestedWorkingCopy()
657
	 */
658
	public ILaunchConfigurationWorkingCopy getNestedWorkingCopy() throws CoreException {
659
		return new LaunchConfigurationWorkingCopy(this);
660
	}
613
661
662
	/* (non-Javadoc)
663
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getParent()
664
	 */
665
	public ILaunchConfigurationWorkingCopy getParent() {
666
		return fParent;
667
	}
668
669
	
614
}
670
}
615
671
(-)core/org/eclipse/debug/core/ILaunchManager.java (+37 lines)
Lines 14-19 Link Here
14
import java.util.Map;
14
import java.util.Map;
15
15
16
import org.eclipse.core.resources.IFile;
16
import org.eclipse.core.resources.IFile;
17
import org.eclipse.core.resources.IResource;
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.debug.core.model.IDebugTarget;
19
import org.eclipse.debug.core.model.IDebugTarget;
19
import org.eclipse.debug.core.model.IPersistableSourceLocator;
20
import org.eclipse.debug.core.model.IPersistableSourceLocator;
Lines 459-464 Link Here
459
	 */
460
	 */
460
	public void removeLaunchListener(ILaunchListener listener);
461
	public void removeLaunchListener(ILaunchListener listener);
461
	
462
	
463
	/**
464
	 * Sets the given launch configuration as the default configuration for the specified
465
	 * resource. There is only one default configuration per resource and this replaces
466
	 * any previously existing launch configuration for the resource, if any. Specifying
467
	 * a configuration of <code>null</code> clears the default configuration for the
468
	 * given resource. 
469
	 * 
470
	 * @param resource resource
471
	 * @param configuration launch configuration or <code>null</code>
472
	 * @exception CoreException if unable to set as default
473
	 * @since 3.3
474
	 * <p>
475
	 * <strong>EXPERIMENTAL</strong>. This method has been added as
476
	 * part of a work in progress. There is no guarantee that this API will
477
	 * remain unchanged during the 3.3 release cycle. Please do not use this API
478
	 * without consulting with the Platform/Debug team.
479
	 * </p>
480
	 */
481
	public void setDefaultConfiguration(IResource resource, ILaunchConfiguration configuration) throws CoreException;
482
	
483
	/**
484
	 * Returns the default launch configuration for the specified resource, or <code>null</code>
485
	 * if none.
486
	 * 
487
	 * @param configuration launch configuration
488
	 * @return launch configuration or <code>null</code>
489
	 * @exception CoreException if an error occurs retrieving the configuration
490
	 * @since 3.3
491
	 * <p>
492
	 * <strong>EXPERIMENTAL</strong>. This method has been added as
493
	 * part of a work in progress. There is no guarantee that this API will
494
	 * remain unchanged during the 3.3 release cycle. Please do not use this API
495
	 * without consulting with the Platform/Debug team.
496
	 * </p>
497
	 */
498
	public ILaunchConfiguration getDefaultConfiguration(IResource resource) throws CoreException;
462
}
499
}
463
500
464
501
(-)core/org/eclipse/debug/core/ILaunchConfigurationWorkingCopy.java (-1 / +45 lines)
Lines 50-56 Link Here
50
	 * a handle to the resulting launch configuration.
50
	 * a handle to the resulting launch configuration.
51
	 * Has no effect if this configuration does not need saving.
51
	 * Has no effect if this configuration does not need saving.
52
	 * Creates the underlying file if not yet created.
52
	 * Creates the underlying file if not yet created.
53
	 * 
53
	 * <p>
54
	 * <strong>EXPERIMENTAL</strong> - Since 3.3, if this is a nested
55
	 * working copy, the contents of this working copy are saved to the
56
	 * parent working copy and the parent working copy is returned without
57
	 * effecting the original launch configuration.
58
	 * </p>
54
	 * @exception CoreException if an exception occurs while 
59
	 * @exception CoreException if an exception occurs while 
55
	 *  writing this configuration to its underlying file.
60
	 *  writing this configuration to its underlying file.
56
	 */
61
	 */
Lines 231-234 Link Here
231
	 * @since 3.3
236
	 * @since 3.3
232
	 */
237
	 */
233
	public void removeModes(Set modes);
238
	public void removeModes(Set modes);
239
	
240
	/**
241
	 * Returns a working copy of this working copy. Changes to the working copy will
242
	 * be applied to this working copy when saved. The working copy will
243
	 * refer to this launch configuration as its parent. Changes are only
244
	 * saved to the underlying original configuration when the root working
245
	 * copy is saved.
246
	 * 
247
	 * @return a working copy of this working copy
248
	 * @exception CoreException if this method fails. Reasons include:
249
	 * <ul>
250
	 * <li>An exception occurs while initializing the contents of the
251
	 * working copy from this configuration's underlying storage.</li>
252
	 * </ul>
253
	 * @see ILaunchConfigurationWorkingCopy#getOriginal()
254
	 * @see ILaunchConfigurationWorkingCopy#getParent()
255
	 * @since 3.3
256
	 * <p>
257
	 * <strong>EXPERIMENTAL</strong>. This method has been added as
258
	 * part of a work in progress. There is no guarantee that this API will
259
	 * remain unchanged during the 3.3 release cycle. Please do not use this API
260
	 * without consulting with the Platform/Debug team.
261
	 * </p>
262
	 */
263
	public ILaunchConfigurationWorkingCopy getNestedWorkingCopy() throws CoreException;	
264
	
265
	/**
266
	 * Returns the parent of this working copy or <code>null</code> if this working
267
	 * copy is not a nested copy of another working copy.
268
	 * 
269
	 * @return parent or <code>null</code>
270
	 * <p>
271
	 * <strong>EXPERIMENTAL</strong>. This method has been added as
272
	 * part of a work in progress. There is no guarantee that this API will
273
	 * remain unchanged during the 3.3 release cycle. Please do not use this API
274
	 * without consulting with the Platform/Debug team.
275
	 * </p>
276
	 */
277
	public ILaunchConfigurationWorkingCopy getParent();
234
}
278
}

Return to bug 74480