1
/*******************************************************************************
2
* Copyright (c) 2009 QNX Software Systems 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
9
* QNX Software Systems - initial API and implementation
10
* Freescale Semiconductor
11
*******************************************************************************/
12
package org.eclipse.cdt.launch.internal.ui;
15
import java.util.ArrayList;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.List;
20
import org.eclipse.cdt.launch.internal.MultiLaunchConfigurationDelegate;
21
import org.eclipse.cdt.launch.internal.MultiLaunchConfigurationDelegate.LaunchElement;
22
import org.eclipse.cdt.launch.internal.MultiLaunchConfigurationDelegate.LaunchElement.EPostLaunchAction;
23
import org.eclipse.cdt.launch.ui.ComboControlledStackComposite;
24
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.debug.core.DebugPlugin;
26
import org.eclipse.debug.core.ILaunchConfiguration;
27
import org.eclipse.debug.core.ILaunchConfigurationType;
28
import org.eclipse.debug.core.ILaunchManager;
29
import org.eclipse.debug.internal.ui.DebugUIPlugin;
30
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationFilteredTree;
31
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
32
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupFilter;
33
import org.eclipse.debug.ui.ILaunchGroup;
34
import org.eclipse.jface.dialogs.IDialogConstants;
35
import org.eclipse.jface.dialogs.TitleAreaDialog;
36
import org.eclipse.jface.viewers.ISelection;
37
import org.eclipse.jface.viewers.ISelectionChangedListener;
38
import org.eclipse.jface.viewers.IStructuredSelection;
39
import org.eclipse.jface.viewers.SelectionChangedEvent;
40
import org.eclipse.jface.viewers.StructuredSelection;
41
import org.eclipse.jface.viewers.TreeViewer;
42
import org.eclipse.jface.viewers.Viewer;
43
import org.eclipse.jface.viewers.ViewerFilter;
44
import org.eclipse.swt.SWT;
45
import org.eclipse.swt.events.ModifyEvent;
46
import org.eclipse.swt.events.ModifyListener;
47
import org.eclipse.swt.events.SelectionAdapter;
48
import org.eclipse.swt.events.SelectionEvent;
49
import org.eclipse.swt.graphics.Rectangle;
50
import org.eclipse.swt.layout.GridData;
51
import org.eclipse.swt.layout.GridLayout;
52
import org.eclipse.swt.widgets.Button;
53
import org.eclipse.swt.widgets.Combo;
54
import org.eclipse.swt.widgets.Composite;
55
import org.eclipse.swt.widgets.Control;
56
import org.eclipse.swt.widgets.Label;
57
import org.eclipse.swt.widgets.Shell;
58
import org.eclipse.swt.widgets.Text;
59
import org.eclipse.swt.widgets.Tree;
60
import org.eclipse.ui.dialogs.FilteredTree;
61
import org.eclipse.ui.dialogs.PatternFilter;
66
* Dialog to select launch configuration(s)
68
public class MultiLaunchConfigurationSelectionDialog extends TitleAreaDialog implements ISelectionChangedListener {
69
private ViewerFilter[] fFilters = null;
70
private ISelection fSelection;
71
private ILaunchGroup[] launchGroups;
73
private EPostLaunchAction action = EPostLaunchAction.NONE;
74
private Object actionParam;
75
private boolean isDefaultMode;
76
private ViewerFilter emptyTypeFilter;
77
private IStructuredSelection fInitialSelection;
78
private ComboControlledStackComposite fStackComposite;
79
private Label fDelayAmountLabel;
80
private Text fDelayAmountWidget; // in seconds
81
private boolean fForEditing; // true if dialog was opened to edit an entry, otherwise it was opened to add one
83
public MultiLaunchConfigurationSelectionDialog(Shell shell, String initMode, boolean forEditing) {
85
LaunchConfigurationManager manager = DebugUIPlugin.getDefault().getLaunchConfigurationManager();
86
launchGroups = manager.getLaunchGroups();
88
fForEditing = forEditing;
90
setShellStyle(getShellStyle() | SWT.RESIZE);
91
emptyTypeFilter = new ViewerFilter() {
92
public boolean select(Viewer viewer, Object parentElement, Object element) {
93
if (element instanceof ILaunchConfigurationType) {
95
ILaunchConfigurationType type = (ILaunchConfigurationType) element;
96
return getLaunchManager().getLaunchConfigurations(type).length > 0;
97
} catch (CoreException e) {
106
protected ILaunchManager getLaunchManager() {
107
return DebugPlugin.getDefault().getLaunchManager();
110
protected Control createContents(Composite parent) {
111
Control x = super.createContents(parent);
113
setErrorMessage(null);
117
protected Control createDialogArea(Composite parent2) {
118
Composite comp = (Composite) super.createDialogArea(parent2);
121
getShell().setText(fForEditing ? LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.13") : LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.12")); //$NON-NLS-1$ //$NON-NLS-2$
123
// dialog message area (not title bar)
124
setTitle(fForEditing ? LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.15") : LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.14")); //$NON-NLS-1$ //$NON-NLS-2$
126
fStackComposite = new ComboControlledStackComposite(comp, SWT.NONE);
127
HashMap<String, ILaunchGroup> modes = new HashMap<String, ILaunchGroup>();
128
for (ILaunchGroup launchGroup : launchGroups) {
129
if (!modes.containsKey(launchGroup.getMode())) {
130
modes.put(launchGroup.getMode(), launchGroup);
133
if (this.mode.equals(MultiLaunchConfigurationDelegate.DEFAULT_MODE)) {
135
this.mode = "run"; //$NON-NLS-1$
136
ILaunchConfiguration[] configs = getSelectedLaunchConfigurations();
137
if (configs.length > 0) {
138
// we care only about the first selected element
139
for (Iterator<String> iterator = modes.keySet().iterator(); iterator.hasNext();) {
140
String mode = iterator.next();
141
if (configs[0].supportsMode(mode)) {
147
} catch (Exception e) {
150
for (Iterator<String> iterator = modes.keySet().iterator(); iterator.hasNext();) {
151
String mode = iterator.next();
152
ILaunchGroup launchGroup = modes.get(mode);
153
LaunchConfigurationFilteredTree fTree = new LaunchConfigurationFilteredTree(fStackComposite.getStackParent(), SWT.MULTI
154
| SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), launchGroup, fFilters);
156
fStackComposite.addItem(label, fTree);
157
fTree.createViewControl();
158
ViewerFilter[] filters = fTree.getViewer().getFilters();
159
for (ViewerFilter viewerFilter : filters) {
160
if (viewerFilter instanceof LaunchGroupFilter) {
161
fTree.getViewer().removeFilter(viewerFilter);
164
fTree.getViewer().addFilter(emptyTypeFilter);
165
fTree.getViewer().addSelectionChangedListener(this);
166
if (launchGroup.getMode().equals(this.mode)) {
167
fStackComposite.setSelection(label);
169
if (fInitialSelection!=null) {
171
fTree.getViewer().setSelection(fInitialSelection, true);
174
fStackComposite.setLabelText(LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.4")); //$NON-NLS-1$
175
fStackComposite.pack();
176
Rectangle bounds = fStackComposite.getBounds();
178
GridData data = ((GridData) fStackComposite.getLayoutData());
180
data = new GridData(GridData.FILL_BOTH);
181
fStackComposite.setLayoutData(data);
183
data.heightHint = Math.max(convertHeightInCharsToPixels(15), bounds.height);
184
data.widthHint = Math.max(convertWidthInCharsToPixels(40), bounds.width);
185
fStackComposite.getCombo().addSelectionListener(new SelectionAdapter() {
186
public void widgetSelected(SelectionEvent e) {
187
mode = ((Combo) e.widget).getText();
190
// "Use default mode" checkbox. Use a parent composite to provide consistent left-side padding
191
Composite checkboxComp = new Composite(comp, SWT.NONE);
192
checkboxComp.setLayout(new GridLayout(1, false));
193
checkboxComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
194
Button checkBox = new Button(checkboxComp, SWT.CHECK);
195
checkBox.setText(LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.5")); //$NON-NLS-1$
196
checkBox.addSelectionListener(new SelectionAdapter() {
197
public void widgetSelected(SelectionEvent e) {
198
isDefaultMode = ((Button) e.widget).getSelection();
201
checkBox.setSelection(isDefaultMode);
203
createPostLaunchControl(comp);
207
private void createPostLaunchControl(Composite parent) {
208
Composite comp = new Composite(parent, SWT.NONE);
209
comp.setLayout(new GridLayout(4, false));
210
comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
211
Label label = new Label(comp, SWT.NONE);
212
label.setText(LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.8")); //$NON-NLS-1$
213
Combo combo = new Combo(comp, SWT.READ_ONLY);
214
combo.add(LaunchElement.actionEnumToStr(EPostLaunchAction.NONE));
215
combo.add(LaunchElement.actionEnumToStr(EPostLaunchAction.WAIT_FOR_TERMINATION));
216
combo.add(LaunchElement.actionEnumToStr(EPostLaunchAction.DELAY));
217
combo.addSelectionListener(new SelectionAdapter() {
218
public void widgetSelected(SelectionEvent e) {
219
final String actionStr = ((Combo) e.widget).getText();
220
action = MultiLaunchConfigurationDelegate.LaunchElement.strToActionEnum(actionStr);
221
showHideDelayAmountWidgets();
225
combo.setText(MultiLaunchConfigurationDelegate.LaunchElement.actionEnumToStr(action));
227
fDelayAmountLabel = new Label(comp, SWT.NONE);
228
fDelayAmountLabel.setText(LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.9")); //$NON-NLS-1$
230
fDelayAmountWidget = new Text(comp, SWT.SINGLE | SWT.BORDER);
231
GridData gridData = new GridData();
232
gridData.widthHint = convertWidthInCharsToPixels(8);
233
fDelayAmountWidget.setLayoutData(gridData);
234
fDelayAmountWidget.addModifyListener(new ModifyListener(){
235
public void modifyText(ModifyEvent e) {
236
String text = ((Text)e.widget).getText();
238
actionParam = new Integer(Integer.parseInt(text));
240
catch (NumberFormatException exc) {
246
if (actionParam instanceof Integer) {
247
fDelayAmountWidget.setText(((Integer)actionParam).toString());
250
showHideDelayAmountWidgets();
253
private void showHideDelayAmountWidgets() {
254
final boolean visible = action == EPostLaunchAction.DELAY;
255
fDelayAmountLabel.setVisible(visible);
256
fDelayAmountWidget.setVisible(visible);
259
public ILaunchConfiguration[] getSelectedLaunchConfigurations() {
260
List<ILaunchConfiguration> configs = new ArrayList<ILaunchConfiguration>();
261
if (fSelection != null && !fSelection.isEmpty()) {
262
for (Iterator<?> iter = ((IStructuredSelection)fSelection).iterator(); iter.hasNext();) {
263
Object selection = iter.next();
264
if (selection instanceof ILaunchConfiguration) {
265
configs.add((ILaunchConfiguration)selection);
269
return configs.toArray(new ILaunchConfiguration[configs.size()]);
272
public String getMode() {
273
return isDefaultMode ? MultiLaunchConfigurationDelegate.DEFAULT_MODE : mode;
276
public EPostLaunchAction getAction(){
280
public Object getActionParam(){
284
public static MultiLaunchConfigurationSelectionDialog createDialog(Shell shell, String groupId, boolean forEditing) {
285
return new MultiLaunchConfigurationSelectionDialog(shell, groupId, forEditing);
289
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
291
public void selectionChanged(SelectionChangedEvent event) {
293
// This listener gets called for a selection change in the launch
294
// configuration viewer embedded in the dialog. Problem is, there are
295
// numerous viewers--one for each platform debug ILaunchGroup (run,
296
// debug, profile). These viewers are stacked, so only one is ever
297
// visible to the user. During initialization, we get a selection change
298
// notification for every viewer. We need to ignore all but the one that
299
// matters--the visible one.
302
final Control topControl = fStackComposite.getTopControl();
303
if (topControl instanceof FilteredTree) {
304
final TreeViewer viewer = ((FilteredTree)topControl).getViewer();
305
if (viewer != null) {
306
topTree = viewer.getTree();
309
if (topTree == null) {
313
boolean selectionIsForVisibleViewer = false;
314
final Object src = event.getSource();
315
if (src instanceof Viewer) {
316
final Control viewerControl = ((Viewer)src).getControl();
317
if (viewerControl == topTree) {
318
selectionIsForVisibleViewer = true;
322
if (!selectionIsForVisibleViewer) {
326
fSelection = event.getSelection();
330
protected void validate() {
331
Button ok_button = getButton(IDialogConstants.OK_ID);
332
boolean isValid = true;
333
if (getSelectedLaunchConfigurations().length < 1) {
334
setErrorMessage(LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.7")); //$NON-NLS-1$
337
setErrorMessage(null);
342
// must have only one selection
343
if (getSelectedLaunchConfigurations().length > 1) {
344
setErrorMessage(LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.11")); //$NON-NLS-1$
351
if (action == EPostLaunchAction.DELAY) {
352
isValid = (actionParam instanceof Integer) && ((Integer)actionParam > 0);
353
setErrorMessage(isValid ? null : LaunchMessages.getString("MultiLaunchConfigurationSelectionDialog.10")); //$NON-NLS-1$
357
if (ok_button != null)
358
ok_button.setEnabled(isValid);
361
public void setInitialSelection(LaunchElement el) {
362
action = el.getAction();
363
actionParam = el.getActionParam();
364
isDefaultMode = el.getMode().equals(MultiLaunchConfigurationDelegate.DEFAULT_MODE);
365
fInitialSelection = new StructuredSelection(el.getData());
366
fSelection = fInitialSelection;