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

(-)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 247-250 Link Here
247
	 * @since 3.3
252
	 * @since 3.3
248
	 */
253
	 */
249
	public void removeModes(Set modes);
254
	public void removeModes(Set modes);
255
	
256
	/**
257
	 * Returns a working copy of this working copy. Changes to the working copy will
258
	 * be applied to this working copy when saved. The working copy will
259
	 * refer to this launch configuration as its parent. Changes are only
260
	 * saved to the underlying original configuration when the root working
261
	 * copy is saved.
262
	 * 
263
	 * @return a working copy of this working copy
264
	 * @exception CoreException if this method fails. Reasons include:
265
	 * <ul>
266
	 * <li>An exception occurs while initializing the contents of the
267
	 * working copy from this configuration's underlying storage.</li>
268
	 * </ul>
269
	 * @see ILaunchConfigurationWorkingCopy#getOriginal()
270
	 * @see ILaunchConfigurationWorkingCopy#getParent()
271
	 * @since 3.3
272
	 * <p>
273
	 * <strong>EXPERIMENTAL</strong>. This method has been added as
274
	 * part of a work in progress. There is no guarantee that this API will
275
	 * remain unchanged during the 3.3 release cycle. Please do not use this API
276
	 * without consulting with the Platform/Debug team.
277
	 * </p>
278
	 */
279
	public ILaunchConfigurationWorkingCopy getNestedWorkingCopy() throws CoreException;	
280
	
281
	/**
282
	 * Returns the parent of this working copy or <code>null</code> if this working
283
	 * copy is not a nested copy of another working copy.
284
	 * 
285
	 * @return parent or <code>null</code>
286
	 * <p>
287
	 * <strong>EXPERIMENTAL</strong>. This method has been added as
288
	 * part of a work in progress. There is no guarantee that this API will
289
	 * remain unchanged during the 3.3 release cycle. Please do not use this API
290
	 * without consulting with the Platform/Debug team.
291
	 * </p>
292
	 */
293
	public ILaunchConfigurationWorkingCopy getParent();
250
}
294
}
(-)core/org/eclipse/debug/internal/core/LaunchManager.java (-1 / +106 lines)
Lines 58-63 Link Here
58
import org.eclipse.core.resources.IResourceDeltaVisitor;
58
import org.eclipse.core.resources.IResourceDeltaVisitor;
59
import org.eclipse.core.resources.IResourceProxy;
59
import org.eclipse.core.resources.IResourceProxy;
60
import org.eclipse.core.resources.IResourceProxyVisitor;
60
import org.eclipse.core.resources.IResourceProxyVisitor;
61
import org.eclipse.core.resources.ProjectScope;
61
import org.eclipse.core.resources.ResourcesPlugin;
62
import org.eclipse.core.resources.ResourcesPlugin;
62
import org.eclipse.core.runtime.CoreException;
63
import org.eclipse.core.runtime.CoreException;
63
import org.eclipse.core.runtime.IConfigurationElement;
64
import org.eclipse.core.runtime.IConfigurationElement;
Lines 66-76 Link Here
66
import org.eclipse.core.runtime.ISafeRunnable;
67
import org.eclipse.core.runtime.ISafeRunnable;
67
import org.eclipse.core.runtime.IStatus;
68
import org.eclipse.core.runtime.IStatus;
68
import org.eclipse.core.runtime.ListenerList;
69
import org.eclipse.core.runtime.ListenerList;
70
import org.eclipse.core.runtime.Path;
69
import org.eclipse.core.runtime.Platform;
71
import org.eclipse.core.runtime.Platform;
70
import org.eclipse.core.runtime.PlatformObject;
72
import org.eclipse.core.runtime.PlatformObject;
71
import org.eclipse.core.runtime.Preferences;
73
import org.eclipse.core.runtime.Preferences;
72
import org.eclipse.core.runtime.SafeRunner;
74
import org.eclipse.core.runtime.SafeRunner;
73
import org.eclipse.core.runtime.Status;
75
import org.eclipse.core.runtime.Status;
76
import org.eclipse.core.runtime.preferences.InstanceScope;
74
import org.eclipse.core.variables.VariablesPlugin;
77
import org.eclipse.core.variables.VariablesPlugin;
75
import org.eclipse.debug.core.DebugException;
78
import org.eclipse.debug.core.DebugException;
76
import org.eclipse.debug.core.DebugPlugin;
79
import org.eclipse.debug.core.DebugPlugin;
Lines 78-83 Link Here
78
import org.eclipse.debug.core.ILaunchConfiguration;
81
import org.eclipse.debug.core.ILaunchConfiguration;
79
import org.eclipse.debug.core.ILaunchConfigurationListener;
82
import org.eclipse.debug.core.ILaunchConfigurationListener;
80
import org.eclipse.debug.core.ILaunchConfigurationType;
83
import org.eclipse.debug.core.ILaunchConfigurationType;
84
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
81
import org.eclipse.debug.core.ILaunchDelegate;
85
import org.eclipse.debug.core.ILaunchDelegate;
82
import org.eclipse.debug.core.ILaunchListener;
86
import org.eclipse.debug.core.ILaunchListener;
83
import org.eclipse.debug.core.ILaunchManager;
87
import org.eclipse.debug.core.ILaunchManager;
Lines 95-100 Link Here
95
import org.eclipse.debug.internal.core.sourcelookup.SourceContainerType;
99
import org.eclipse.debug.internal.core.sourcelookup.SourceContainerType;
96
import org.eclipse.debug.internal.core.sourcelookup.SourcePathComputer;
100
import org.eclipse.debug.internal.core.sourcelookup.SourcePathComputer;
97
import org.eclipse.osgi.service.environment.Constants;
101
import org.eclipse.osgi.service.environment.Constants;
102
import org.osgi.service.prefs.BackingStoreException;
98
import org.w3c.dom.Document;
103
import org.w3c.dom.Document;
99
import org.w3c.dom.Element;
104
import org.w3c.dom.Element;
100
import org.w3c.dom.Node;
105
import org.w3c.dom.Node;
Lines 117-122 Link Here
117
	
122
	
118
	
123
	
119
	/**
124
	/**
125
	 * 
126
	 */
127
	private static final String DEFAULT_CONFIGURATION = "defaultConfiguration";
128
	/**
120
	 * Constants for xml node names
129
	 * Constants for xml node names
121
	 * 
130
	 * 
122
	 * @since 3.3
131
	 * @since 3.3
Lines 2335-2339 Link Here
2335
            }
2344
            }
2336
        }
2345
        }
2337
        return title;
2346
        return title;
2338
    }	
2347
    }
2348
2349
	/* (non-Javadoc)
2350
	 * @see org.eclipse.debug.core.ILaunchManager#getDefaultConfiguration(org.eclipse.core.resources.IResource)
2351
	 */
2352
	public ILaunchConfiguration getDefaultConfiguration(IResource resource) throws CoreException {
2353
		IProject project = resource.getProject();
2354
		if (project != null) {
2355
			org.osgi.service.prefs.Preferences projectNode = getProjectNode(resource);
2356
			String configValue = projectNode.get(DEFAULT_CONFIGURATION, null);
2357
			if (configValue != null) {
2358
				// shared config
2359
				IFile file = project.getFile(Path.fromPortableString(configValue));
2360
				return getLaunchConfiguration(file);
2361
			} else {
2362
				org.osgi.service.prefs.Preferences instanceNode = getInstanceNode(resource);
2363
				configValue = instanceNode.get(DEFAULT_CONFIGURATION, null);
2364
				if (configValue != null) {
2365
					// local config
2366
					return getLaunchConfiguration(configValue);
2367
				}
2368
			}
2369
		}
2370
		return null;
2371
	}
2372
2373
	/* (non-Javadoc)
2374
	 * @see org.eclipse.debug.core.ILaunchManager#setDefaultConfiguration(org.eclipse.core.resources.IResource, org.eclipse.debug.core.ILaunchConfiguration)
2375
	 */
2376
	public void setDefaultConfiguration(IResource resource, ILaunchConfiguration configuration) throws CoreException {
2377
		IProject project = resource.getProject();
2378
		if (project == null) {
2379
			throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
2380
					DebugPlugin.INTERNAL_ERROR, "Illegal argument: can only set default launch configuration on and within projects.", null));
2381
		}
2382
		if (configuration != null && !configuration.isLocal()) {
2383
			if (!configuration.getFile().getProject().equals(project)) {
2384
				throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
2385
						DebugPlugin.INTERNAL_ERROR, "A shared launch configuration must be shared in same project that it is a default configuration for.", null));
2386
			}
2387
		}
2388
		
2389
		// remove previous settings, if any
2390
		org.osgi.service.prefs.Preferences projectNode = getProjectNode(resource);
2391
		projectNode.remove(DEFAULT_CONFIGURATION);
2392
		flush(projectNode);
2393
		org.osgi.service.prefs.Preferences instanceNode = getInstanceNode(resource);
2394
		instanceNode.remove(DEFAULT_CONFIGURATION);
2395
		flush(instanceNode);
2396
		
2397
		if (configuration != null) {
2398
			org.osgi.service.prefs.Preferences node = null;
2399
			String configurationValue = null;
2400
			if (configuration.isLocal()) {
2401
				// for local configurations, use workspace (instance) scope preferences
2402
				node = instanceNode;
2403
				if (configuration.isWorkingCopy()) {
2404
					configurationValue = ((ILaunchConfigurationWorkingCopy)configuration).getOriginal().getMemento();
2405
				} else {
2406
					configurationValue = configuration.getMemento();
2407
				}
2408
			} else {
2409
				// for shared configurations, use project scope preferences
2410
				node = projectNode;
2411
				configurationValue = configuration.getFile().getProjectRelativePath().toPortableString();
2412
			}
2413
			node.put(DEFAULT_CONFIGURATION, configurationValue);
2414
			flush(node);
2415
		}
2416
		
2417
	}	
2418
	
2419
	private void flush(org.osgi.service.prefs.Preferences node) {
2420
		try {
2421
			node.flush();
2422
		} catch (BackingStoreException e) {
2423
			// TODO Auto-generated catch block
2424
			e.printStackTrace();
2425
		}
2426
	}
2427
	
2428
	private org.osgi.service.prefs.Preferences getProjectNode(IResource resource) {
2429
		org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode();
2430
		ProjectScope scope = new ProjectScope(resource.getProject());
2431
		node = scope.getNode(DebugPlugin.getUniqueIdentifier());
2432
		IProject project = resource.getProject();
2433
		if (!resource.equals(project)) {
2434
			node = node.node(resource.getProjectRelativePath().toString());
2435
		}
2436
		return node;
2437
	}
2438
	
2439
	private org.osgi.service.prefs.Preferences getInstanceNode(IResource resource) {
2440
		org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode();
2441
		node = node.node(InstanceScope.SCOPE).node(DebugPlugin.getUniqueIdentifier());
2442
		return node.node(resource.getFullPath().makeRelative().toString());
2443
	}
2339
}
2444
}
(-)core/org/eclipse/debug/internal/core/LaunchConfigurationWorkingCopy.java (-25 / +79 lines)
Lines 87-92 Link Here
87
	private IContainer fContainer;
87
	private IContainer fContainer;
88
	
88
	
89
	/**
89
	/**
90
	 * Parent working copy.
91
	 * @since 3.3
92
	 */
93
	private LaunchConfigurationWorkingCopy fParent = null;
94
	
95
	/**
90
	 * Constructs a working copy of the specified launch 
96
	 * Constructs a working copy of the specified launch 
91
	 * configuration.
97
	 * configuration.
92
	 * 
98
	 * 
Lines 104-109 Link Here
104
	}
110
	}
105
	
111
	
106
	/**
112
	/**
113
	 * Constructs a working copy of the specified launch configuration as its parent.
114
	 * 
115
	 * @param parent launch configuration to make
116
	 *  a working copy of
117
	 * @exception CoreException if unable to initialize this
118
	 *  working copy's attributes based on the original configuration
119
	 */
120
	protected LaunchConfigurationWorkingCopy(LaunchConfigurationWorkingCopy parent) throws CoreException {
121
		super(parent.getLocation());
122
		setName(parent.getName());
123
		copyFrom(parent);
124
		setOriginal((LaunchConfiguration) parent.getOriginal());
125
		fParent = parent;
126
		fSuppressChange = false;
127
	}	
128
	
129
	/**
107
	 * Constructs a copy of the specified launch 
130
	 * Constructs a copy of the specified launch 
108
	 * configuration, with the given (new) name.
131
	 * configuration, with the given (new) name.
109
	 * 
132
	 * 
Lines 150-184 Link Here
150
	 * @see ILaunchConfigurationWorkingCopy#doSave()
173
	 * @see ILaunchConfigurationWorkingCopy#doSave()
151
	 */
174
	 */
152
	public synchronized ILaunchConfiguration doSave() throws CoreException {
175
	public synchronized ILaunchConfiguration doSave() throws CoreException {
153
		if (isDirty()) {
176
		if (fParent == null) {
154
			boolean useRunnable= true;
177
			if (isDirty()) {
155
			if (isLocal()) {
178
				boolean useRunnable= true;
156
				if (isMoved()) {
179
				if (isLocal()) {
157
					// If this config was moved from a shared location, saving
180
					if (isMoved()) {
158
					// it will delete the original from the workspace. Use runnable.
181
						// If this config was moved from a shared location, saving
159
					useRunnable= !isNew() && !getOriginal().isLocal();
182
						// it will delete the original from the workspace. Use runnable.
183
						useRunnable= !isNew() && !getOriginal().isLocal();
184
					} else {
185
						useRunnable= false;
186
					}
187
				}
188
	
189
				if (useRunnable) {
190
					IWorkspaceRunnable wr = new IWorkspaceRunnable() {
191
						public void run(IProgressMonitor pm) throws CoreException {
192
							doSave0();
193
						}
194
					};
195
					
196
					ResourcesPlugin.getWorkspace().run(wr, null, 0, null);
160
				} else {
197
				} else {
161
					useRunnable= false;
198
					//file is persisted in the metadata not the workspace
199
					doSave0();
162
				}
200
				}
201
	
202
				getLaunchManager().setMovedFromTo(null, null);
163
			}
203
			}
164
204
	
165
			if (useRunnable) {
205
			return new LaunchConfiguration(getLocation());
166
				IWorkspaceRunnable wr = new IWorkspaceRunnable() {
206
		} else {
167
					public void run(IProgressMonitor pm) throws CoreException {
207
			// save to parent working copy
168
						doSave0();
208
			fParent.setName(getName());
169
					}
209
			fParent.copyFrom(this);
170
				};
210
			return fParent;
171
				
172
				ResourcesPlugin.getWorkspace().run(wr, null, 0, null);
173
			} else {
174
				//file is persisted in the metadata not the workspace
175
				doSave0();
176
			}
177
178
			getLaunchManager().setMovedFromTo(null, null);
179
		}
211
		}
180
181
		return new LaunchConfiguration(getLocation());
182
	}
212
	}
183
213
184
	
214
	
Lines 635-640 Link Here
635
			catch (CoreException ce) {DebugPlugin.log(ce);}
665
			catch (CoreException ce) {DebugPlugin.log(ce);}
636
		}
666
		}
637
	}
667
	}
668
	
669
	/* (non-Javadoc)
670
	 * @see org.eclipse.debug.internal.core.LaunchConfiguration#getWorkingCopy()
671
	 */
672
	public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException {
673
		if (fParent == null) {
674
			return super.getWorkingCopy();
675
		} else {
676
			return getNestedWorkingCopy();
677
		}
678
	}
638
679
680
	/* (non-Javadoc)
681
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getNestedWorkingCopy()
682
	 */
683
	public ILaunchConfigurationWorkingCopy getNestedWorkingCopy() throws CoreException {
684
		return new LaunchConfigurationWorkingCopy(this);
685
	}
686
687
	/* (non-Javadoc)
688
	 * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getParent()
689
	 */
690
	public ILaunchConfigurationWorkingCopy getParent() {
691
		return fParent;
692
	}
639
}
693
}
640
694
(-)ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java (+1 lines)
Lines 115-120 Link Here
115
	// Property pages
115
	// Property pages
116
	public static final String PROCESS_PROPERTY_PAGE = PREFIX + "process_property_page_context"; //$NON-NLS-1$
116
	public static final String PROCESS_PROPERTY_PAGE = PREFIX + "process_property_page_context"; //$NON-NLS-1$
117
	public static final String PROCESS_PAGE_RUN_AT = PREFIX + "process_page_run_at_time_widget"; //$NON-NLS-1$
117
	public static final String PROCESS_PAGE_RUN_AT = PREFIX + "process_page_run_at_time_widget"; //$NON-NLS-1$
118
	public static final String EXECUTION_PROPERTY_PAGE = PREFIX + "execution_property_page"; //$NON-NLS-1$
118
	
119
	
119
	// Launch configuration dialog pages
120
	// Launch configuration dialog pages
120
	public static final String LAUNCH_CONFIGURATION_DIALOG_COMMON_TAB = PREFIX + "launch_configuration_dialog_common_tab"; //$NON-NLS-1$
121
	public static final String LAUNCH_CONFIGURATION_DIALOG_COMMON_TAB = PREFIX + "launch_configuration_dialog_common_tab"; //$NON-NLS-1$
(-)plugin.xml (+7 lines)
Lines 1394-1399 Link Here
1394
            </or>
1394
            </or>
1395
         </enabledWhen>
1395
         </enabledWhen>
1396
      </page>
1396
      </page>
1397
      <page
1398
            adaptable="true"
1399
            class="org.eclipse.debug.internal.ui.launchConfigurations.properties.ExecutionPropertiesPage"
1400
            id="org.eclipse.debug.ui.properties.execution"
1401
            name="Execution"
1402
            objectClass="org.eclipse.core.resources.IResource">
1403
      </page>
1397
   </extension>
1404
   </extension>
1398
<!-- commands and their bindings
1405
<!-- commands and their bindings
1399
NOTE: 
1406
NOTE: 
(-)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
}
(-)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
}

Return to bug 74480