7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
8 * |
8 * |
9 * Initial Contributors: |
9 * Initial Contributors: |
10 * Nokia Corporation - initial contribution. |
10 * Nokia Corporation - initial contribution. |
11 * |
11 * |
12 * Contributors: |
12 * Contributors: |
13 * |
13 * |
14 * Description: |
14 * Description: |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 package com.nokia.cdt.internal.debug.launch.newwizard; |
18 package com.nokia.cdt.internal.debug.launch.newwizard; |
19 |
19 |
20 import java.io.File; |
20 import java.io.File; |
21 import java.text.MessageFormat; |
21 import java.text.MessageFormat; |
22 import java.util.Iterator; |
22 import java.util.ArrayList; |
23 import java.util.LinkedHashSet; |
23 import java.util.LinkedHashSet; |
24 import java.util.List; |
24 import java.util.List; |
25 import java.util.Set; |
25 import java.util.Set; |
26 |
26 |
27 import org.eclipse.cdt.core.model.CoreModel; |
27 import org.eclipse.cdt.core.model.CoreModel; |
45 import org.eclipse.swt.SWT; |
45 import org.eclipse.swt.SWT; |
46 import org.eclipse.swt.events.ControlAdapter; |
46 import org.eclipse.swt.events.ControlAdapter; |
47 import org.eclipse.swt.events.ControlEvent; |
47 import org.eclipse.swt.events.ControlEvent; |
48 import org.eclipse.swt.events.DisposeEvent; |
48 import org.eclipse.swt.events.DisposeEvent; |
49 import org.eclipse.swt.events.DisposeListener; |
49 import org.eclipse.swt.events.DisposeListener; |
|
50 import org.eclipse.swt.events.FocusAdapter; |
|
51 import org.eclipse.swt.events.FocusEvent; |
50 import org.eclipse.swt.events.ModifyEvent; |
52 import org.eclipse.swt.events.ModifyEvent; |
51 import org.eclipse.swt.events.ModifyListener; |
53 import org.eclipse.swt.events.ModifyListener; |
52 import org.eclipse.swt.events.SelectionAdapter; |
54 import org.eclipse.swt.events.SelectionAdapter; |
53 import org.eclipse.swt.events.SelectionEvent; |
55 import org.eclipse.swt.events.SelectionEvent; |
54 import org.eclipse.swt.layout.GridData; |
56 import org.eclipse.swt.layout.GridData; |
88 private Combo sisFile; |
90 private Combo sisFile; |
89 private Text sisEdit; |
91 private Text sisEdit; |
90 private Button sisBrowse; |
92 private Button sisBrowse; |
91 private Composite installPackageUI; |
93 private Composite installPackageUI; |
92 |
94 |
93 private Set<IPath> remotePathEntries = new LinkedHashSet<IPath>(); |
95 private List<IPath> remotePathEntries = new ArrayList<IPath>(); |
|
96 private List<IPath> projectGeneratedRemotePaths; |
94 |
97 |
95 protected DebugRunProcessDialog(Shell shell, LaunchWizardData data) { |
98 protected DebugRunProcessDialog(Shell shell, LaunchWizardData data) { |
96 super(shell, data); |
99 super(shell, data); |
97 } |
100 } |
98 |
101 |
135 |
138 |
136 /** |
139 /** |
137 * |
140 * |
138 */ |
141 */ |
139 protected void saveRemoteProgramEntries() { |
142 protected void saveRemoteProgramEntries() { |
|
143 // in case user was typing, ensure that entry is present |
|
144 if(remoteProgramViewer != null) { |
|
145 IPath currentPath = PathUtils.createPath(remoteProgramViewer.getCombo().getText().trim()); |
|
146 remotePathEntries.remove(currentPath); |
|
147 remotePathEntries.add(0, currentPath); // MRU |
|
148 } |
|
149 |
|
150 // make a set, removing user dupes, and also removing the entries we added |
140 Set<IPath> uniqueRemotePathEntries = new LinkedHashSet<IPath>(remotePathEntries); |
151 Set<IPath> uniqueRemotePathEntries = new LinkedHashSet<IPath>(remotePathEntries); |
141 |
152 if (projectGeneratedRemotePaths != null) |
142 // in case user was typing, ensure that entry is present |
153 uniqueRemotePathEntries.removeAll(projectGeneratedRemotePaths); |
143 if(remoteProgramViewer != null) |
154 |
144 uniqueRemotePathEntries.add(PathUtils.createPath(remoteProgramViewer.getCombo().getText().trim())); |
155 // truncate size, removing from end |
145 |
156 List<IPath> mruPathEntries = new ArrayList<IPath>(uniqueRemotePathEntries); |
146 for (Iterator<IPath> iter = uniqueRemotePathEntries.iterator(); iter.hasNext(); ) { |
157 while (mruPathEntries.size() > 10) { |
147 IPath path = iter.next(); |
158 mruPathEntries.remove(mruPathEntries.size() - 1); |
148 if (path.isEmpty() || data.getExes().contains(path)) |
159 } |
149 iter.remove(); |
160 |
150 } |
161 String pathSoup = TextUtils.catenateStrings(mruPathEntries.toArray(), "|"); //$NON-NLS-1$ |
151 |
|
152 // truncate size |
|
153 while (uniqueRemotePathEntries.size() > 10) |
|
154 uniqueRemotePathEntries.remove(uniqueRemotePathEntries.iterator().next()); |
|
155 |
|
156 String pathSoup = TextUtils.catenateStrings(uniqueRemotePathEntries.toArray(), "|"); //$NON-NLS-1$ |
|
157 LaunchPlugin.getDefault().getPreferenceStore().setValue(USER_REMOTE_PATHS, pathSoup); |
162 LaunchPlugin.getDefault().getPreferenceStore().setValue(USER_REMOTE_PATHS, pathSoup); |
158 } |
163 } |
159 |
|
160 |
164 |
161 /** |
165 /** |
162 * |
166 * |
163 */ |
167 */ |
164 protected void loadRemoteProgramEntries() { |
168 protected void loadRemoteProgramEntries() { |
232 |
236 |
233 installPackageCheckbox = new Button(composite, SWT.CHECK); |
237 installPackageCheckbox = new Button(composite, SWT.CHECK); |
234 GridDataFactory.fillDefaults().applyTo(installPackageCheckbox); |
238 GridDataFactory.fillDefaults().applyTo(installPackageCheckbox); |
235 |
239 |
236 installPackageCheckbox.setText(Messages.getString("DebugRunProcessDialog.InstallBeforeLaunchLabel")); //$NON-NLS-1$ |
240 installPackageCheckbox.setText(Messages.getString("DebugRunProcessDialog.InstallBeforeLaunchLabel")); //$NON-NLS-1$ |
|
241 installPackageCheckbox.setToolTipText(Messages.getString("DebugRunProcessDialog.SISCheckboxTooltip")); //$NON-NLS-1$ |
|
242 |
237 installPackageUI = new Composite(composite, SWT.NONE); |
243 installPackageUI = new Composite(composite, SWT.NONE); |
238 GridDataFactory.fillDefaults().indent(INDENT, 0).applyTo(installPackageUI); |
244 GridDataFactory.fillDefaults().indent(INDENT, 0).applyTo(installPackageUI); |
239 |
245 |
240 createSISContents(installPackageUI); |
246 createSISContents(installPackageUI); |
241 |
247 |
416 } |
422 } |
417 |
423 |
418 protected void initUI() { |
424 protected void initUI() { |
419 List<IPath> exes = data.getLaunchableExes(); |
425 List<IPath> exes = data.getLaunchableExes(); |
420 projectExecutableViewer.setInput(exes); |
426 projectExecutableViewer.setInput(exes); |
|
427 |
|
428 // this path may either be a project-relative or remote path |
421 IPath exeSelectionPath = data.getExeSelectionPath(); |
429 IPath exeSelectionPath = data.getExeSelectionPath(); |
422 if (exeSelectionPath.equals(Path.EMPTY) && !exes.isEmpty()) |
430 if (exeSelectionPath.equals(Path.EMPTY) && !exes.isEmpty()) |
423 exeSelectionPath = exes.get(0); |
431 exeSelectionPath = exes.get(0); |
|
432 |
424 if (!Path.EMPTY.equals(exeSelectionPath)) { |
433 if (!Path.EMPTY.equals(exeSelectionPath)) { |
|
434 // keep previous path if possible... |
|
435 IPath remotePath = exeSelectionPath; |
|
436 if (data.getExes().contains(remotePath)) { |
|
437 // unless that was actually a host-side path, which should be converted |
|
438 remotePath = createSuggestedRemotePath(exeSelectionPath); |
|
439 } else { |
|
440 // selection is already a remote path; map back to project if possible |
|
441 IPath projPath = getHostFileForRemoteLocation(exeSelectionPath); |
|
442 if (projPath != null) { |
|
443 exeSelectionPath = projPath; |
|
444 } |
|
445 else { |
|
446 // remote path does not correspond to anything; select some project exe so |
|
447 // the combo isn't empty |
|
448 exeSelectionPath = exes.get(0); |
|
449 } |
|
450 } |
425 projectExecutableViewer.setSelection(new StructuredSelection(exeSelectionPath)); |
451 projectExecutableViewer.setSelection(new StructuredSelection(exeSelectionPath)); |
426 IPath remotePath = exeSelectionPath; |
452 |
427 if (remoteProgramViewer != null) { |
453 if (remoteProgramViewer != null) { |
428 if (!remotePathEntries.contains(remotePath)) { |
454 if (!remotePathEntries.contains(remotePath)) { |
429 remotePath = createSuggestedRemotePath(exeSelectionPath); |
455 remotePathEntries.add(0, remotePath); // MRU |
430 remotePathEntries.add(remotePath); |
|
431 remoteProgramViewer.add(remotePath); |
456 remoteProgramViewer.add(remotePath); |
432 } |
457 } |
433 remoteProgramViewer.setSelection(new StructuredSelection(remotePath)); |
458 remoteProgramViewer.setSelection(new StructuredSelection(remotePath)); |
434 } |
459 } |
435 } |
460 } |
436 |
461 |
437 if (data.getExeSelection() == EExeSelection.USE_PROJECT_EXECUTABLE && exeSelectionPath != null) { |
462 if (data.getExeSelection() == EExeSelection.USE_PROJECT_EXECUTABLE && exeSelectionPath != null) { |
438 projectExecutableRadioButton.forceFocus(); |
463 projectExecutableViewer.getControl().forceFocus(); |
439 } |
464 } |
440 |
465 |
441 if (data.getExeSelection() == EExeSelection.USE_REMOTE_EXECUTABLE && exeSelectionPath != null) { |
466 if (data.getExeSelection() == EExeSelection.USE_REMOTE_EXECUTABLE && exeSelectionPath != null) { |
442 remoteExecutableRadioButton.forceFocus(); |
467 remoteProgramViewer.getControl().forceFocus(); |
443 } |
468 } |
444 |
469 |
445 if (data.getExeSelection() == EExeSelection.ATTACH_TO_PROCESS) { |
470 if (data.getExeSelection() == EExeSelection.ATTACH_TO_PROCESS) { |
446 attachToProcessRadioButton.forceFocus(); |
471 attachToProcessRadioButton.forceFocus(); |
447 } |
472 } |
453 |
478 |
454 |
479 |
455 private IPath createSuggestedRemotePath(IPath exeSelectionPath) { |
480 private IPath createSuggestedRemotePath(IPath exeSelectionPath) { |
456 String filename = exeSelectionPath.lastSegment(); |
481 String filename = exeSelectionPath.lastSegment(); |
457 return PathUtils.createPath("C:/sys/bin").append(filename); //$NON-NLS-1$ |
482 return PathUtils.createPath("C:/sys/bin").append(filename); //$NON-NLS-1$ |
|
483 } |
|
484 |
|
485 |
|
486 /** |
|
487 * Get the host-side file for a given remote location. Opposite of |
|
488 * {@link #createSuggestedRemotePath(IPath)}. |
|
489 * @param path |
|
490 * @return host path or <code>null</code> |
|
491 */ |
|
492 private IPath getHostFileForRemoteLocation(IPath path) { |
|
493 for (IPath exe : data.getExes()) { |
|
494 // no... we don't have any knowledge (yet) of the actual install path, |
|
495 // so comparing the exact path will fail if the user edited it. |
|
496 // IPath remoteSuggested = createSuggestedRemotePath(exe); |
|
497 |
|
498 // be pretty loose in the matching for now |
|
499 if (exe.lastSegment().equalsIgnoreCase(path.lastSegment())) { |
|
500 return exe; |
|
501 } |
|
502 } |
|
503 return null; |
458 } |
504 } |
459 |
505 |
460 /** |
506 /** |
461 * Allow selecting an executable detected to be built by the program. |
507 * Allow selecting an executable detected to be built by the program. |
462 * @param radioGroup |
508 * @param radioGroup |
464 private void createProjectExecutableRadioButton(Composite radioGroup) { |
510 private void createProjectExecutableRadioButton(Composite radioGroup) { |
465 projectExecutableRadioButton = new Button(radioGroup, SWT.RADIO); |
511 projectExecutableRadioButton = new Button(radioGroup, SWT.RADIO); |
466 GridDataFactory.fillDefaults().grab(false, false).applyTo(projectExecutableRadioButton); |
512 GridDataFactory.fillDefaults().grab(false, false).applyTo(projectExecutableRadioButton); |
467 projectExecutableRadioButton.setText(Messages.getString("DebugRunProcessDialog.LaunchProjectExeLabel")); //$NON-NLS-1$ |
513 projectExecutableRadioButton.setText(Messages.getString("DebugRunProcessDialog.LaunchProjectExeLabel")); //$NON-NLS-1$ |
468 projectExecutableRadioButton.setData(UID, "radio_project_executable"); //$NON-NLS-1$ |
514 projectExecutableRadioButton.setData(UID, "radio_project_executable"); //$NON-NLS-1$ |
|
515 projectExecutableRadioButton.setToolTipText(Messages.getString("DebugRunProcessDialog.LaunchProjectExecutableRadioTooltip")); //$NON-NLS-1$ |
|
516 |
469 |
517 |
470 projectExecutableViewer = new ComboViewer(radioGroup, SWT.READ_ONLY); |
518 projectExecutableViewer = new ComboViewer(radioGroup, SWT.READ_ONLY); |
471 GridDataFactory.fillDefaults().grab(true, false).applyTo(projectExecutableViewer.getControl()); |
519 GridDataFactory.fillDefaults().grab(true, false).applyTo(projectExecutableViewer.getControl()); |
472 projectExecutableViewer.getControl().setData(UID, "combo_project_executable"); //$NON-NLS-1$ |
520 projectExecutableViewer.getControl().setData(UID, "combo_project_executable"); //$NON-NLS-1$ |
|
521 projectExecutableViewer.getControl().setToolTipText(Messages.getString("DebugRunProcessDialog.LaunchProjectExecutableSelectorTooltip")); //$NON-NLS-1$ |
473 |
522 |
474 projectExecutableViewer.setContentProvider(new ArrayContentProvider()); |
523 projectExecutableViewer.setContentProvider(new ArrayContentProvider()); |
475 projectExecutableViewer.setLabelProvider(new LabelProvider() { |
524 projectExecutableViewer.setLabelProvider(new LabelProvider() { |
476 @Override |
525 @Override |
477 public String getText(Object element) { |
526 public String getText(Object element) { |
492 projectExecutableViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
541 projectExecutableViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
493 |
542 |
494 public void selectionChanged(SelectionChangedEvent event) { |
543 public void selectionChanged(SelectionChangedEvent event) { |
495 Object sel = ((IStructuredSelection) event.getSelection()).getFirstElement(); |
544 Object sel = ((IStructuredSelection) event.getSelection()).getFirstElement(); |
496 if (sel instanceof IPath) { |
545 if (sel instanceof IPath) { |
497 data.setExeSelectionPath((IPath) sel); |
546 if (projectExecutableRadioButton.getSelection()) { |
|
547 data.setExeSelectionPath((IPath) sel); |
|
548 } |
498 |
549 |
499 // track the default remote program from the executable, for easy editing |
550 // track the default remote program from the executable, for easy editing |
500 if (remoteProgramViewer != null) { |
551 if (remoteProgramViewer != null && !remoteExecutableRadioButton.getSelection()) { |
501 IPath exeSelectionPath = createSuggestedRemotePath(data.getExeSelectionPath()); |
552 IPath exeSelectionPath = createSuggestedRemotePath(data.getExeSelectionPath()); |
502 // path should already be in model |
553 // path should already be in model |
503 remoteProgramViewer.setSelection(new StructuredSelection(exeSelectionPath)); |
554 remoteProgramViewer.setSelection(new StructuredSelection(exeSelectionPath)); |
504 } |
555 } |
505 |
556 |
532 remoteExecutableRadioButton = new Button(radioGroup, SWT.RADIO); |
583 remoteExecutableRadioButton = new Button(radioGroup, SWT.RADIO); |
533 GridDataFactory.fillDefaults().grab(false, false).applyTo(remoteExecutableRadioButton); |
584 GridDataFactory.fillDefaults().grab(false, false).applyTo(remoteExecutableRadioButton); |
534 remoteExecutableRadioButton.setText(Messages.getString("DebugRunProcessDialog.LaunchRemoteProgLabel")); //$NON-NLS-1$ |
585 remoteExecutableRadioButton.setText(Messages.getString("DebugRunProcessDialog.LaunchRemoteProgLabel")); //$NON-NLS-1$ |
535 |
586 |
536 remoteExecutableRadioButton.setData(UID, "radio_remote_program"); //$NON-NLS-1$ |
587 remoteExecutableRadioButton.setData(UID, "radio_remote_program"); //$NON-NLS-1$ |
|
588 remoteExecutableRadioButton.setToolTipText(Messages.getString("DebugRunProcessDialog.LaunchRemoteProgramRadioTooltip")); //$NON-NLS-1$ |
537 |
589 |
538 remoteProgramViewer = new ComboViewer(radioGroup, SWT.BORDER); |
590 remoteProgramViewer = new ComboViewer(radioGroup, SWT.BORDER); |
539 GridDataFactory.fillDefaults().grab(true, false).applyTo(remoteProgramViewer.getControl()); |
591 GridDataFactory.fillDefaults().grab(true, false).applyTo(remoteProgramViewer.getControl()); |
540 |
592 |
541 remotePathEntries.addAll(data.getExes()); |
593 projectGeneratedRemotePaths = new ArrayList<IPath>(); |
|
594 for (IPath launchable : data.getLaunchableExes()) { |
|
595 projectGeneratedRemotePaths.add(createSuggestedRemotePath(launchable)); |
|
596 } |
|
597 |
|
598 // add the entries before the user MRU entries |
|
599 remotePathEntries.addAll(0, projectGeneratedRemotePaths); |
542 |
600 |
543 remoteProgramViewer.setContentProvider(new ArrayContentProvider()); |
601 remoteProgramViewer.setContentProvider(new ArrayContentProvider()); |
544 remoteProgramViewer.setLabelProvider(new LabelProvider() { |
602 remoteProgramViewer.setLabelProvider(new LabelProvider() { |
545 @Override |
603 @Override |
546 public String getText(Object element) { |
604 public String getText(Object element) { |
548 return PathUtils.convertPathToWindows((IPath) element); |
606 return PathUtils.convertPathToWindows((IPath) element); |
549 return super.getText(element); |
607 return super.getText(element); |
550 } |
608 } |
551 }); |
609 }); |
552 remoteProgramViewer.setInput(remotePathEntries); |
610 remoteProgramViewer.setInput(remotePathEntries); |
553 remoteProgramViewer.getCombo().setVisibleItemCount(remotePathEntries.size()); |
611 remoteProgramViewer.getCombo().setVisibleItemCount(Math.min(10, remotePathEntries.size())); |
554 |
|
555 |
612 |
556 remoteProgramViewer.setData(UID, "combo_remote_program"); //$NON-NLS-1$ |
613 remoteProgramViewer.setData(UID, "combo_remote_program"); //$NON-NLS-1$ |
|
614 remoteProgramViewer.getControl().setToolTipText(Messages.getString("DebugRunProcessDialog.LaunchRemoteProgramSelectorTooltip")); //$NON-NLS-1$ |
557 |
615 |
558 remoteExecutableRadioButton.addSelectionListener(new SelectionAdapter() { |
616 remoteExecutableRadioButton.addSelectionListener(new SelectionAdapter() { |
559 @Override |
617 @Override |
560 public void widgetSelected(SelectionEvent e) { |
618 public void widgetSelected(SelectionEvent e) { |
561 handleRemoteExecutableRadioSelected(); |
619 handleRemoteExecutableRadioSelected(); |
563 |
621 |
564 }); |
622 }); |
565 |
623 |
566 remoteProgramViewer.getCombo().addModifyListener(new ModifyListener() { |
624 remoteProgramViewer.getCombo().addModifyListener(new ModifyListener() { |
567 public void modifyText(ModifyEvent e) { |
625 public void modifyText(ModifyEvent e) { |
568 data.setExeSelectionPath(PathUtils.createPath(remoteProgramViewer.getCombo().getText().trim())); |
626 IPath path = PathUtils.createPath(remoteProgramViewer.getCombo().getText().trim()); |
|
627 if (remoteExecutableRadioButton.getSelection()) { |
|
628 data.setExeSelectionPath(path); |
|
629 } |
|
630 |
|
631 if (!projectExecutableRadioButton.getSelection()) { |
|
632 IPath projPath = getHostFileForRemoteLocation(path); |
|
633 if (projPath != null) { |
|
634 projectExecutableViewer.setSelection(new StructuredSelection(projPath)); |
|
635 } |
|
636 } |
|
637 |
569 validate(); |
638 validate(); |
|
639 } |
|
640 }); |
|
641 |
|
642 remoteProgramViewer.getCombo().addFocusListener(new FocusAdapter() { |
|
643 /* (non-Javadoc) |
|
644 * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent) |
|
645 */ |
|
646 @Override |
|
647 public void focusLost(FocusEvent e) { |
|
648 IPath path = PathUtils.createPath(remoteProgramViewer.getCombo().getText().trim()); |
|
649 |
|
650 // MRU behavior |
|
651 remotePathEntries.remove(path); |
|
652 remotePathEntries.add(0, path); |
570 } |
653 } |
571 }); |
654 }); |
572 } |
655 } |
573 |
656 |
574 private void handleRemoteExecutableRadioSelected() { |
657 private void handleRemoteExecutableRadioSelected() { |
592 attachToProcessRadioButton = new Button(radioGroup, SWT.RADIO); |
675 attachToProcessRadioButton = new Button(radioGroup, SWT.RADIO); |
593 GridDataFactory.fillDefaults().grab(false, false).applyTo(attachToProcessRadioButton); |
676 GridDataFactory.fillDefaults().grab(false, false).applyTo(attachToProcessRadioButton); |
594 attachToProcessRadioButton.setText(Messages.getString("DebugRunProcessDialog.AttachLabel")); //$NON-NLS-1$ |
677 attachToProcessRadioButton.setText(Messages.getString("DebugRunProcessDialog.AttachLabel")); //$NON-NLS-1$ |
595 |
678 |
596 attachToProcessRadioButton.setData(UID, "radio_attach_to_process"); //$NON-NLS-1$ |
679 attachToProcessRadioButton.setData(UID, "radio_attach_to_process"); //$NON-NLS-1$ |
597 |
680 attachToProcessRadioButton.setToolTipText(Messages.getString("DebugRunProcessDialog.AttachProcessRadioTooltip")); //$NON-NLS-1$ |
|
681 |
598 Label label = new Label(radioGroup, SWT.WRAP); |
682 Label label = new Label(radioGroup, SWT.WRAP); |
599 GridDataFactory.fillDefaults().grab(false, false).align(SWT.LEFT, SWT.CENTER).applyTo(label); |
683 GridDataFactory.fillDefaults().grab(false, false).align(SWT.LEFT, SWT.CENTER).applyTo(label); |
600 |
684 |
601 label.setText(Messages.getString("DebugRunProcessDialog.AttachAddlMsg")); //$NON-NLS-1$ |
685 label.setText(Messages.getString("DebugRunProcessDialog.AttachAddlMsg")); //$NON-NLS-1$ |
602 |
686 |