|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.cdt.internal.debug.launch.newwizard; |
|
19 |
|
20 import java.io.File; |
|
21 import java.text.MessageFormat; |
|
22 |
|
23 import org.eclipse.cdt.core.model.CoreModel; |
|
24 import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; |
|
25 import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener; |
|
26 import org.eclipse.core.resources.IProject; |
|
27 import org.eclipse.core.runtime.IPath; |
|
28 import org.eclipse.core.runtime.IStatus; |
|
29 import org.eclipse.core.runtime.Path; |
|
30 import org.eclipse.core.runtime.Status; |
|
31 import org.eclipse.jface.layout.GridDataFactory; |
|
32 import org.eclipse.jface.layout.GridLayoutFactory; |
|
33 import org.eclipse.jface.resource.JFaceResources; |
|
34 import org.eclipse.jface.viewers.ArrayContentProvider; |
|
35 import org.eclipse.jface.viewers.ComboViewer; |
|
36 import org.eclipse.jface.viewers.ISelectionChangedListener; |
|
37 import org.eclipse.jface.viewers.IStructuredSelection; |
|
38 import org.eclipse.jface.viewers.LabelProvider; |
|
39 import org.eclipse.jface.viewers.SelectionChangedEvent; |
|
40 import org.eclipse.jface.viewers.StructuredSelection; |
|
41 import org.eclipse.swt.SWT; |
|
42 import org.eclipse.swt.events.ControlAdapter; |
|
43 import org.eclipse.swt.events.ControlEvent; |
|
44 import org.eclipse.swt.events.DisposeEvent; |
|
45 import org.eclipse.swt.events.DisposeListener; |
|
46 import org.eclipse.swt.events.FocusAdapter; |
|
47 import org.eclipse.swt.events.FocusEvent; |
|
48 import org.eclipse.swt.events.ModifyEvent; |
|
49 import org.eclipse.swt.events.ModifyListener; |
|
50 import org.eclipse.swt.events.SelectionAdapter; |
|
51 import org.eclipse.swt.events.SelectionEvent; |
|
52 import org.eclipse.swt.layout.GridData; |
|
53 import org.eclipse.swt.widgets.Button; |
|
54 import org.eclipse.swt.widgets.Combo; |
|
55 import org.eclipse.swt.widgets.Composite; |
|
56 import org.eclipse.swt.widgets.Control; |
|
57 import org.eclipse.swt.widgets.FileDialog; |
|
58 import org.eclipse.swt.widgets.Label; |
|
59 import org.eclipse.swt.widgets.Link; |
|
60 import org.eclipse.swt.widgets.Shell; |
|
61 import org.eclipse.swt.widgets.Text; |
|
62 import org.eclipse.ui.dialogs.PreferencesUtil; |
|
63 |
|
64 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin; |
|
65 import com.nokia.carbide.cdt.builder.project.ICarbideBuildConfiguration; |
|
66 import com.nokia.carbide.cdt.builder.project.ICarbideProjectInfo; |
|
67 import com.nokia.carbide.cdt.builder.project.ISISBuilderInfo; |
|
68 import com.nokia.cdt.internal.debug.launch.newwizard.LaunchOptionsData.EExeSelection; |
|
69 import com.nokia.cpp.internal.api.utils.core.PathUtils; |
|
70 import com.nokia.cpp.internal.api.utils.ui.BrowseDialogUtils; |
|
71 |
|
72 /** |
|
73 * This dialog allows in-depth configuration of the debug/run process options. |
|
74 */ |
|
75 public class DebugRunProcessDialog extends AbstractLaunchSettingsDialog implements ICProjectDescriptionListener { |
|
76 private ComboViewer projectExecutableViewer; |
|
77 private Text remoteProgramEntry; |
|
78 private Button projectExecutableRadioButton; |
|
79 private Button remoteExecutableRadioButton; |
|
80 private Button attachToProcessRadioButton; |
|
81 |
|
82 private Label packageInfoLabel; |
|
83 private Button installPackageCheckbox; |
|
84 private Combo sisFile; |
|
85 private Text sisEdit; |
|
86 private Button sisBrowse; |
|
87 private Composite installPackageUI; |
|
88 |
|
89 protected DebugRunProcessDialog(Shell shell, LaunchOptionsData data) { |
|
90 super(shell, data); |
|
91 } |
|
92 |
|
93 |
|
94 /* (non-Javadoc) |
|
95 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) |
|
96 */ |
|
97 @Override |
|
98 protected Control createDialogArea(Composite parent) { |
|
99 Composite composite = initDialogArea(parent, |
|
100 MessageFormat.format("Change {0} Process", data.getModeLabel()), |
|
101 data.isDebug() ? LaunchWizardHelpIds.WIZARD_DIALOG_CHANGE_DEBUG_PROCESS : |
|
102 LaunchWizardHelpIds.WIZARD_DIALOG_CHANGE_RUN_PROCESS); |
|
103 |
|
104 |
|
105 createProcessSelector(composite); |
|
106 |
|
107 Label sep = new Label(composite, SWT.NONE); |
|
108 GridDataFactory.fillDefaults().applyTo(sep); |
|
109 |
|
110 createPackageConfiguration(composite); |
|
111 |
|
112 initUI(); |
|
113 |
|
114 validate(); |
|
115 |
|
116 return composite; |
|
117 } |
|
118 |
|
119 |
|
120 private void createProcessSelector(Composite composite) { |
|
121 Label label; |
|
122 |
|
123 label = new Label(composite, SWT.WRAP); |
|
124 label.setText(MessageFormat.format("{0} method:", data.getModeLabel())); |
|
125 label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT)); |
|
126 |
|
127 GridDataFactory.fillDefaults().grab(true, false).applyTo(composite); |
|
128 |
|
129 Composite radioGroup = new Composite(composite, SWT.NONE); |
|
130 GridDataFactory.fillDefaults().grab(true, false).applyTo(radioGroup); |
|
131 GridLayoutFactory.fillDefaults().extendedMargins(INDENT, 0, 0, 0).numColumns(2).applyTo(radioGroup); |
|
132 |
|
133 createProjectExecutableRadioButton(radioGroup); |
|
134 createRemoteExecutableRadioButton(radioGroup); |
|
135 |
|
136 label = new Label(radioGroup, SWT.SEPARATOR | SWT.HORIZONTAL); |
|
137 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(label); |
|
138 |
|
139 createAttachToProcessRadioButton(radioGroup); |
|
140 |
|
141 String msg; |
|
142 if (data.isDebug()) |
|
143 msg = "Configure how to debug the program. The initial settings reflect the debug capabilities of the selected device and the SIS builder settings."; |
|
144 else |
|
145 msg = "Configure how to run the program."; |
|
146 setMessage(msg); |
|
147 |
|
148 switch (data.getExeSelection()) { |
|
149 case USE_PROJECT_EXECUTABLE: |
|
150 projectExecutableRadioButton.setSelection(true); |
|
151 break; |
|
152 case USE_REMOTE_EXECUTABLE: |
|
153 remoteExecutableRadioButton.setSelection(true); |
|
154 break; |
|
155 case ATTACH_TO_PROCESS: |
|
156 attachToProcessRadioButton.setSelection(true); |
|
157 break; |
|
158 } |
|
159 } |
|
160 |
|
161 |
|
162 private void createPackageConfiguration(Composite composite) { |
|
163 Label label; |
|
164 |
|
165 label = new Label(composite, SWT.WRAP); |
|
166 label.setText(MessageFormat.format("Deploy method:", data.getModeLabel())); |
|
167 label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT)); |
|
168 |
|
169 GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); |
|
170 |
|
171 packageInfoLabel = new Label(composite, SWT.WRAP); |
|
172 GridDataFactory.fillDefaults().grab(true, false).applyTo(packageInfoLabel); |
|
173 composite.addControlListener(new ControlAdapter() { |
|
174 @Override |
|
175 public void controlResized(ControlEvent e) { |
|
176 packageInfoLabel.pack(); |
|
177 } |
|
178 }); |
|
179 |
|
180 installPackageCheckbox = new Button(composite, SWT.CHECK); |
|
181 GridDataFactory.fillDefaults().applyTo(installPackageCheckbox); |
|
182 |
|
183 installPackageCheckbox.setText("Install package before launch"); |
|
184 installPackageUI = new Composite(composite, SWT.NONE); |
|
185 GridDataFactory.fillDefaults().indent(INDENT, 0).applyTo(installPackageUI); |
|
186 |
|
187 createSISContents(installPackageUI); |
|
188 |
|
189 |
|
190 installPackageCheckbox.addSelectionListener(new SelectionAdapter() { |
|
191 @Override |
|
192 public void widgetSelected(SelectionEvent e) { |
|
193 data.setInstallPackage(installPackageCheckbox.getSelection()); |
|
194 updatePackageUI(); |
|
195 } |
|
196 }); |
|
197 |
|
198 |
|
199 if (data.requiresInstallPackage()) { |
|
200 installPackageCheckbox.setSelection(true); |
|
201 } |
|
202 |
|
203 updateSisFile(); |
|
204 updatePackageUI(); |
|
205 } |
|
206 |
|
207 protected void createSISContents(Composite composite) { |
|
208 GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(2).applyTo(composite); |
|
209 |
|
210 final IProject project = data.getProject(); |
|
211 ICarbideProjectInfo cpi = CarbideBuilderPlugin.getBuildManager().getProjectInfo(project); |
|
212 if (cpi != null) { |
|
213 final Label sisLabel = new Label(composite, SWT.NONE); |
|
214 sisLabel.setText("SIS File to Install:"); |
|
215 GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).span(1, 1).applyTo(sisLabel); |
|
216 sisLabel.setToolTipText("Specify which SIS file to install on the phone prior to launching"); |
|
217 sisLabel.setData(UID, "DebugRunProcessDialog.sisLabel"); |
|
218 |
|
219 sisFile = new Combo(composite, SWT.READ_ONLY); |
|
220 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1).grab(true, false).applyTo(sisLabel); |
|
221 sisFile.setToolTipText("Specify which SIS file to install on the phone prior to launching"); |
|
222 sisFile.add("None"); //$NON-NLS-1$ |
|
223 sisFile.setData(UID, "DebugRunProcessDialog.sisFile"); |
|
224 |
|
225 sisFile.addSelectionListener(new SelectionAdapter() { |
|
226 @Override |
|
227 public void widgetSelected(SelectionEvent e) { |
|
228 updateSisFile(); |
|
229 } |
|
230 }); |
|
231 |
|
232 ICarbideBuildConfiguration config = cpi.getDefaultConfiguration(); |
|
233 for (ISISBuilderInfo info : config.getSISBuilderInfoList()) { |
|
234 IPath sisPath = info.getSigningType() == ISISBuilderInfo.DONT_SIGN ? info.getUnsignedSISFullPath() : info.getSignedSISFullPath(); |
|
235 sisFile.add(sisPath.toOSString()); |
|
236 } |
|
237 |
|
238 // select the first sis file if any, otherwise select none |
|
239 if (sisFile.getItemCount() > 1) { |
|
240 sisFile.select(1); |
|
241 } else { |
|
242 sisFile.select(0); |
|
243 } |
|
244 |
|
245 // listen for events so we can detect if they click on the link below and add new sis info. |
|
246 CoreModel.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(this, CProjectDescriptionEvent.APPLIED); |
|
247 |
|
248 composite.addDisposeListener(new DisposeListener() { |
|
249 |
|
250 public void widgetDisposed(DisposeEvent e) { |
|
251 CoreModel.getDefault().getProjectDescriptionManager().removeCProjectDescriptionListener(DebugRunProcessDialog.this); |
|
252 } |
|
253 }); |
|
254 |
|
255 Link link = new Link(composite, SWT.NONE); |
|
256 link.setText("<a>" + "Modify SIS builder settings for build configuration" + "...</a>"); |
|
257 GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1).grab(true, false).applyTo(link); |
|
258 link.addSelectionListener(new SelectionAdapter() { |
|
259 public void widgetSelected(SelectionEvent e) { |
|
260 PreferencesUtil.createPropertyDialogOn(getShell(), project, "com.nokia.carbide.cdt.internal.builder.ui.CarbideBuildConfigurationsPage", null, null).open(); |
|
261 } |
|
262 }); |
|
263 link.setData(UID, "DebugRunProcessDialog.link"); |
|
264 } else { |
|
265 // not a Carbide project, just an executable. show a browse/edit combo |
|
266 // to let them select a sis file if they want to. |
|
267 final Label sisLabel = new Label(composite, SWT.NONE); |
|
268 sisLabel.setText("SIS File to Install:"); //$NON-NLS-1$ |
|
269 GridDataFactory.swtDefaults().span(2, 1).applyTo(sisLabel); |
|
270 sisLabel.setToolTipText("Specify which SIS file to install on the phone prior to launching"); |
|
271 sisLabel.setData(UID, "DebugRunProcessDialog.sisLabel"); |
|
272 |
|
273 sisEdit = new Text(composite, SWT.BORDER); |
|
274 GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(sisEdit); |
|
275 sisEdit.setToolTipText("Specify which SIS file to install on the phone prior to launching"); |
|
276 sisEdit.addModifyListener(new ModifyListener() { |
|
277 public void modifyText(ModifyEvent e) { |
|
278 updateSisFile(); |
|
279 validate(); |
|
280 } |
|
281 }); |
|
282 sisEdit.setData(UID, "DebugRunProcessDialog.sisEdit"); |
|
283 |
|
284 sisBrowse = new Button(composite, SWT.NONE); |
|
285 sisBrowse.setText("Browse..."); |
|
286 sisBrowse.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); |
|
287 sisBrowse.addSelectionListener(new SelectionAdapter() { |
|
288 public void widgetSelected(SelectionEvent evt) { |
|
289 FileDialog dialog = new FileDialog(getShell(), SWT.NONE); |
|
290 |
|
291 dialog.setText("Select installation file"); |
|
292 dialog.setFilterExtensions(new String[] {"*.sis*", "*.*"}); |
|
293 dialog.setFilterNames(new String[] {"Installation Files", "All Files"}); |
|
294 |
|
295 BrowseDialogUtils.initializeFrom(dialog, sisEdit); |
|
296 |
|
297 String result = dialog.open(); |
|
298 if (result != null && new File(result).exists()) { |
|
299 sisEdit.setText(result); |
|
300 updateSisFile(); |
|
301 validate(); |
|
302 } |
|
303 } |
|
304 }); |
|
305 sisBrowse.setData(UID, "DebugRunProcessDialog.sisBrowse"); |
|
306 } |
|
307 } |
|
308 |
|
309 |
|
310 /** |
|
311 * |
|
312 */ |
|
313 protected void updateSisFile() { |
|
314 String sisPath; |
|
315 if (sisFile != null) { |
|
316 sisPath = sisFile.getSelectionIndex() == 0 ? "" : sisFile.getText(); //$NON-NLS-1$ |
|
317 data.setSisPath(sisPath); |
|
318 } else if (sisEdit != null) { |
|
319 sisPath = sisEdit.getText(); |
|
320 data.setSisPath(sisPath); |
|
321 } |
|
322 } |
|
323 |
|
324 |
|
325 private void updatePackageUI() { |
|
326 installPackageUI.setEnabled(data.isInstallPackage()); |
|
327 for (Control kid : installPackageUI.getChildren()) |
|
328 kid.setEnabled(data.isInstallPackage()); |
|
329 } |
|
330 |
|
331 |
|
332 public void handleEvent(CProjectDescriptionEvent event) { |
|
333 if (getShell().isDisposed()) { |
|
334 return; |
|
335 } |
|
336 |
|
337 IProject project = event.getProject() ; |
|
338 |
|
339 if (project != data.getProject()) { |
|
340 return; |
|
341 } |
|
342 |
|
343 if (sisFile != null) { |
|
344 ICarbideProjectInfo cpi = CarbideBuilderPlugin.getBuildManager().getProjectInfo(project); |
|
345 if (cpi != null) { |
|
346 sisFile.removeAll(); |
|
347 |
|
348 sisFile.add("None"); |
|
349 |
|
350 ICarbideBuildConfiguration config = cpi.getDefaultConfiguration(); |
|
351 for (ISISBuilderInfo info : config.getSISBuilderInfoList()) { |
|
352 IPath sisPath = info.getSigningType() == ISISBuilderInfo.DONT_SIGN ? info.getUnsignedSISFullPath() : info.getSignedSISFullPath(); |
|
353 sisFile.add(sisPath.toOSString()); |
|
354 } |
|
355 |
|
356 // select the first sis file if any, otherwise select none |
|
357 if (sisFile.getItemCount() > 1) { |
|
358 sisFile.select(1); |
|
359 } else { |
|
360 sisFile.select(0); |
|
361 } |
|
362 } |
|
363 } |
|
364 } |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 protected void initUI() { |
|
373 projectExecutableViewer.setInput(data.getExes()); |
|
374 |
|
375 if (data.getExeSelection() == EExeSelection.USE_PROJECT_EXECUTABLE && data.getExeSelectionPath() != null) { |
|
376 projectExecutableViewer.setSelection(new StructuredSelection(data.getExeSelectionPath())); |
|
377 projectExecutableRadioButton.forceFocus(); |
|
378 } |
|
379 |
|
380 if (data.getExeSelection() == EExeSelection.USE_REMOTE_EXECUTABLE && data.getExeSelectionPath() != null) { |
|
381 IPath exeSelectionPath = createSuggestedRemotePath(data.getExeSelectionPath()); |
|
382 remoteProgramEntry.setText(PathUtils.convertPathToWindows(exeSelectionPath)); |
|
383 remoteExecutableRadioButton.forceFocus(); |
|
384 } |
|
385 |
|
386 if (data.getExeSelection() == EExeSelection.ATTACH_TO_PROCESS) { |
|
387 attachToProcessRadioButton.forceFocus(); |
|
388 } |
|
389 } |
|
390 |
|
391 |
|
392 private IPath createSuggestedRemotePath(IPath exeSelectionPath) { |
|
393 String filename = exeSelectionPath.lastSegment(); |
|
394 return PathUtils.createPath("C:/sys/bin").append(filename); |
|
395 } |
|
396 |
|
397 /** |
|
398 * Allow selecting an executable detected to be built by the program. |
|
399 * @param radioGroup |
|
400 */ |
|
401 private void createProjectExecutableRadioButton(Composite radioGroup) { |
|
402 projectExecutableRadioButton = new Button(radioGroup, SWT.RADIO); |
|
403 GridDataFactory.fillDefaults().grab(false, false).applyTo(projectExecutableRadioButton); |
|
404 projectExecutableRadioButton.setText("Launch project &executable:"); |
|
405 projectExecutableRadioButton.setData(UID, "radio_project_executable"); |
|
406 |
|
407 projectExecutableViewer = new ComboViewer(radioGroup, SWT.READ_ONLY); |
|
408 GridDataFactory.fillDefaults().grab(true, false).applyTo(projectExecutableViewer.getControl()); |
|
409 projectExecutableViewer.getControl().setData(UID, "combo_project_executable"); |
|
410 |
|
411 projectExecutableViewer.setContentProvider(new ArrayContentProvider()); |
|
412 projectExecutableViewer.setLabelProvider(new LabelProvider() { |
|
413 @Override |
|
414 public String getText(Object element) { |
|
415 if (element instanceof IPath) |
|
416 return ((IPath) element).lastSegment(); |
|
417 return super.getText(element); |
|
418 } |
|
419 }); |
|
420 |
|
421 projectExecutableRadioButton.addSelectionListener(new SelectionAdapter() { |
|
422 @Override |
|
423 public void widgetSelected(SelectionEvent e) { |
|
424 if (projectExecutableRadioButton.getSelection()) { |
|
425 projectExecutableViewer.getControl().setEnabled(true); |
|
426 data.setExeSelection(EExeSelection.USE_PROJECT_EXECUTABLE); |
|
427 |
|
428 validate(); |
|
429 } else { |
|
430 projectExecutableViewer.getControl().setEnabled(false); |
|
431 // another button becomes active and sets the new launch process |
|
432 } |
|
433 } |
|
434 }); |
|
435 |
|
436 projectExecutableViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
|
437 |
|
438 public void selectionChanged(SelectionChangedEvent event) { |
|
439 Object sel = ((IStructuredSelection) event.getSelection()).getFirstElement(); |
|
440 if (sel instanceof IPath) { |
|
441 data.setExeSelectionPath((IPath) sel); |
|
442 |
|
443 // track the default remote program from the executable, for easy editing |
|
444 if (remoteProgramEntry != null) { |
|
445 IPath exeSelectionPath = createSuggestedRemotePath(data.getExeSelectionPath()); |
|
446 remoteProgramEntry.setText(PathUtils.convertPathToWindows(exeSelectionPath)); |
|
447 } |
|
448 |
|
449 validate(); |
|
450 } |
|
451 } |
|
452 }); |
|
453 } |
|
454 |
|
455 /** |
|
456 * Allow user to enter an executable path. |
|
457 * @param radioGroup |
|
458 */ |
|
459 private void createRemoteExecutableRadioButton(Composite radioGroup) { |
|
460 remoteExecutableRadioButton = new Button(radioGroup, SWT.RADIO); |
|
461 GridDataFactory.fillDefaults().grab(false, false).applyTo(remoteExecutableRadioButton); |
|
462 remoteExecutableRadioButton.setText("Launch &remote program:"); |
|
463 |
|
464 remoteExecutableRadioButton.setData(UID, "radio_remote_program"); |
|
465 |
|
466 remoteProgramEntry = new Text(radioGroup, SWT.BORDER); |
|
467 GridDataFactory.fillDefaults().grab(true, false).applyTo(remoteProgramEntry); |
|
468 |
|
469 remoteProgramEntry.setData(UID, "text_remote_program"); |
|
470 |
|
471 remoteExecutableRadioButton.addSelectionListener(new SelectionAdapter() { |
|
472 @Override |
|
473 public void widgetSelected(SelectionEvent e) { |
|
474 if (remoteExecutableRadioButton.getSelection()) { |
|
475 remoteProgramEntry.setEnabled(true); |
|
476 data.setExeSelection(EExeSelection.USE_REMOTE_EXECUTABLE); |
|
477 String symbianPath = PathUtils.convertPathToWindows(remoteProgramEntry.getText()); |
|
478 data.setExeSelectionPath(new Path(symbianPath)); |
|
479 validate(); |
|
480 } else { |
|
481 remoteProgramEntry.setEnabled(false); |
|
482 // another button becomes active and sets the new launch process |
|
483 } |
|
484 } |
|
485 }); |
|
486 |
|
487 remoteProgramEntry.addFocusListener(new FocusAdapter() { |
|
488 @Override |
|
489 public void focusLost(FocusEvent e) { |
|
490 data.setExeSelectionPath(new Path(remoteProgramEntry.getText().trim())); |
|
491 validate(); |
|
492 } |
|
493 }); |
|
494 |
|
495 } |
|
496 |
|
497 /** |
|
498 * Allow user to attach to a process. |
|
499 * @param radioGroup |
|
500 */ |
|
501 private void createAttachToProcessRadioButton(Composite radioGroup) { |
|
502 attachToProcessRadioButton = new Button(radioGroup, SWT.RADIO); |
|
503 GridDataFactory.fillDefaults().grab(false, false).applyTo(attachToProcessRadioButton); |
|
504 attachToProcessRadioButton.setText("&Attach to process:"); |
|
505 |
|
506 attachToProcessRadioButton.setData(UID, "radio_attach_to_process"); |
|
507 |
|
508 Label label = new Label(radioGroup, SWT.WRAP); |
|
509 GridDataFactory.fillDefaults().grab(false, false).align(SWT.LEFT, SWT.CENTER).applyTo(label); |
|
510 |
|
511 label.setText("(selected at launch time)"); |
|
512 |
|
513 attachToProcessRadioButton.addSelectionListener(new SelectionAdapter() { |
|
514 @Override |
|
515 public void widgetSelected(SelectionEvent e) { |
|
516 if (attachToProcessRadioButton.getSelection()) { |
|
517 data.setExeSelection(EExeSelection.ATTACH_TO_PROCESS); |
|
518 data.setExeSelectionPath(null); |
|
519 validate(); |
|
520 } else { |
|
521 // another button becomes active and sets the new launch process |
|
522 } |
|
523 } |
|
524 }); |
|
525 |
|
526 } |
|
527 |
|
528 @Override |
|
529 protected void validate() { |
|
530 IStatus status = Status.OK_STATUS; |
|
531 |
|
532 // check launch method |
|
533 IPath exePath = data.getExeSelectionPath(); |
|
534 switch (data.getExeSelection()) { |
|
535 case USE_PROJECT_EXECUTABLE: |
|
536 if (exePath.isEmpty()) { |
|
537 status = error("The project builds no executables."); |
|
538 } |
|
539 break; |
|
540 case USE_REMOTE_EXECUTABLE: |
|
541 if (exePath.isEmpty()) { |
|
542 status = error("Enter a non-empty executable path."); |
|
543 } else { |
|
544 String exePathString = exePath.toString(); |
|
545 char drive = exePathString.charAt(0); |
|
546 char colon = exePathString.length() < 2 ? 0x0 : exePathString.charAt(1); |
|
547 char root = exePathString.length() < 3 ? 0x0 : exePathString.charAt(2); |
|
548 char lastChar = exePathString.charAt(exePathString.length() - 1); |
|
549 if (!Character.isLetter(drive) || colon != ':' || (root != '\\' && root != '/') || |
|
550 lastChar == '\\' || lastChar == '/' || lastChar == ':') { |
|
551 status = error("The executable path must be absolute."); |
|
552 } else if (exePath.getFileExtension() == null) { |
|
553 status = warning("The executable path should end in a filename."); |
|
554 } |
|
555 } |
|
556 break; |
|
557 case ATTACH_TO_PROCESS: |
|
558 break; |
|
559 } |
|
560 |
|
561 // check SIS selection |
|
562 if (data.isInstallPackage()) { |
|
563 if (sisEdit != null) { |
|
564 String text = sisEdit.getText().trim(); |
|
565 if (text.length() > 0) { |
|
566 // empty is allowed, but if they specify something, make sure |
|
567 // it exists |
|
568 File file = new File(text); |
|
569 if (!file.exists()) { |
|
570 status = error("The SIS file ''{0}'' does not exist.", text); |
|
571 } |
|
572 } |
|
573 } |
|
574 } |
|
575 |
|
576 updateStatus(status); |
|
577 } |
|
578 } |
|
579 |