/******************************************************************************* * Copyright (c) 2006, 2011 PalmSource, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Ewa Matejska (PalmSource) - initial API and implementation * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Martin Oberhuber (Wind River) - [196934] hide disabled system types in remotecdt combo * Yu-Fen Kuo (MontaVista) - [190613] Fix NPE in Remotecdt when RSEUIPlugin has not been loaded * Martin Oberhuber (Wind River) - [cleanup] Avoid using SystemStartHere in production code * Johann Draschwandtner (Wind River) - [231827][remotecdt]Auto-compute default for Remote path * Johann Draschwandtner (Wind River) - [233057][remotecdt]Fix button enablement * Anna Dushistova (MontaVista) - [181517][usability] Specify commands to be run before remote application launch * Anna Dushistova (MontaVista) - [223728] [remotecdt] connection combo is not populated until RSE is activated * Anna Dushistova (MontaVista) - [267951] [remotecdt] Support systemTypes without files subsystem * Anna Dushistova (Mentor Graphics) - [314659] move remote launch/debug to DSF * Anna Dushistova (Mentor Graphics) - moved to org.eclipse.cdt.launch.remote.tabs * Anna Dushistova (Mentor Graphics) - [318052] [remote launch] Properties are not saved/used * Anna Dushistova (Mentor Graphics) - [333453] adapted the fix from RemoteCDSFMainTab.java *******************************************************************************/ package org.eclipse.cdt.launch.remote.tabs; import org.eclipse.cdt.internal.launch.remote.Messages; import org.eclipse.cdt.launch.remote.IRemoteConnectionConfigurationConstants; import org.eclipse.cdt.launch.remote.IRemoteConnectionHostConstants; import org.eclipse.cdt.launch.remote.RSEHelper; import org.eclipse.cdt.launch.ui.CMainTab; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.window.Window; import org.eclipse.rse.core.IRSESystemType; import org.eclipse.rse.core.RSECorePlugin; import org.eclipse.rse.core.model.IHost; import org.eclipse.rse.core.model.IPropertySet; import org.eclipse.rse.files.ui.dialogs.SystemRemoteFileDialog; import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; import org.eclipse.rse.ui.actions.SystemNewConnectionAction; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; public class RemoteCMainTab extends CMainTab { /* Labels and Error Messages */ private static final String REMOTE_PROG_LABEL_TEXT = Messages.RemoteCMainTab_Program; private static final String SKIP_DOWNLOAD_BUTTON_TEXT = Messages.RemoteCMainTab_SkipDownload; private static final String REMOTE_PROG_TEXT_ERROR = Messages.RemoteCMainTab_ErrorNoProgram; private static final String CONNECTION_TEXT_ERROR = Messages.RemoteCMainTab_ErrorNoConnection; private static final String PRE_RUN_LABEL_TEXT = Messages.RemoteCMainTab_Prerun; /* Defaults */ private static final String REMOTE_PATH_DEFAULT = EMPTY_STRING; private static final boolean SKIP_DOWNLOAD_TO_REMOTE_DEFAULT = false; protected Button newRemoteConnectionButton; protected Button remoteConnectionPropertiesButton; protected Button remoteBrowseButton; protected Label connectionLabel; protected Combo connectionCombo; protected Label remoteProgLabel; protected Text remoteProgText; protected Button skipDownloadButton; protected Button useLocalPathButton; SystemNewConnectionAction action = null; private Text preRunText; private Label preRunLabel; private boolean isInitializing = false; public RemoteCMainTab() { this(true); } public RemoteCMainTab(boolean terminalOption) { super(terminalOption); } /* * createControl * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl */ public void createControl(Composite parent) { Composite comp = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); setControl(comp); comp.setLayout(topLayout); /* The RSE Connection dropdown with New button. */ createVerticalSpacer(comp, 1); createRemoteConnectionGroup(comp, 4); /* The Project and local binary location */ createVerticalSpacer(comp, 1); createProjectGroup(comp, 1); createBuildConfigCombo(comp, 1); createExeFileGroup(comp, 1); /* The remote binary location and skip download option */ createVerticalSpacer(comp, 1); createTargetExePathGroup(comp); createDownloadOption(comp); /* If the local binary path changes, modify the remote binary location */ fProgText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent evt) { setLocalPathForRemotePath(); } }); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), "org.eclipse.rse.internal.remotecdt.launchgroup"); //$NON-NLS-1$ // //No more needed according to // https://bugs.eclipse.org/bugs/show_bug.cgi?id=178832 // LaunchUIPlugin.setDialogShell(parent.getShell()); } /* * isValid * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid */ public boolean isValid(ILaunchConfiguration config) { boolean retVal = super.isValid(config); if (retVal == true) { setErrorMessage(null); int currentSelection = connectionCombo.getSelectionIndex(); String connection_name = currentSelection >= 0 ? connectionCombo .getItem(currentSelection) : ""; //$NON-NLS-1$ if (connection_name.equals("")) { //$NON-NLS-1$ setErrorMessage(CONNECTION_TEXT_ERROR); retVal = false; } if (retVal) { String name = remoteProgText.getText().trim(); if (name.length() == 0) { setErrorMessage(REMOTE_PROG_TEXT_ERROR); retVal = false; } } } return retVal; } protected void createRemoteConnectionGroup(Composite parent, int colSpan) { Composite projComp = new Composite(parent, SWT.NONE); GridLayout projLayout = new GridLayout(); projLayout.numColumns = 4; projLayout.marginHeight = 0; projLayout.marginWidth = 0; projComp.setLayout(projLayout); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = colSpan; projComp.setLayoutData(gd); connectionLabel = new Label(projComp, SWT.NONE); connectionLabel.setText(Messages.RemoteCMainTab_Connection); gd = new GridData(); gd.horizontalSpan = 1; connectionLabel.setLayoutData(gd); connectionCombo = new Combo(projComp, SWT.DROP_DOWN | SWT.READ_ONLY); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 1; connectionCombo.setLayoutData(gd); connectionCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { useDefaultsFromConnection(); updatePropertiesButton(); setDirty(true); updateLaunchConfigurationDialog(); } }); newRemoteConnectionButton = createPushButton(projComp, Messages.RemoteCMainTab_New, null); newRemoteConnectionButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent evt) { handleNewRemoteConnectionSelected(); updateLaunchConfigurationDialog(); updateConnectionPulldown(); } }); remoteConnectionPropertiesButton = createPushButton(projComp, Messages.RemoteCMainTab_Properties, null); remoteConnectionPropertiesButton .addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent evt) { handleRemoteConnectionPropertiesSelected(); } }); updateConnectionPulldown(); } /* * createTargetExePath This creates the remote path user-editable textfield * on the Main Tab. */ protected void createTargetExePathGroup(Composite parent) { Composite mainComp = new Composite(parent, SWT.NONE); GridLayout mainLayout = new GridLayout(); mainLayout.numColumns = 2; mainLayout.marginHeight = 0; mainLayout.marginWidth = 0; mainComp.setLayout(mainLayout); GridData gd = new GridData(GridData.FILL_HORIZONTAL); mainComp.setLayoutData(gd); remoteProgLabel = new Label(mainComp, SWT.NONE); remoteProgLabel.setText(REMOTE_PROG_LABEL_TEXT); gd = new GridData(); gd.horizontalSpan = 2; remoteProgLabel.setLayoutData(gd); remoteProgText = new Text(mainComp, SWT.SINGLE | SWT.BORDER); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 1; remoteProgText.setLayoutData(gd); remoteProgText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent evt) { updateLaunchConfigurationDialog(); } }); remoteBrowseButton = createPushButton(mainComp, Messages.RemoteCMainTab_Remote_Path_Browse_Button, null); remoteBrowseButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent evt) { handleRemoteBrowseSelected(); updateLaunchConfigurationDialog(); } }); // Commands to run before execution preRunLabel = new Label(mainComp, SWT.NONE); preRunLabel.setText(PRE_RUN_LABEL_TEXT); gd = new GridData(); gd.horizontalSpan = 2; preRunLabel.setLayoutData(gd); preRunText = new Text(mainComp, SWT.MULTI | SWT.BORDER); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 2; preRunText.setLayoutData(gd); preRunText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent evt) { updateLaunchConfigurationDialog(); } }); } /* * createDownloadOption This creates the skip download check button. */ protected void createDownloadOption(Composite parent) { Composite mainComp = new Composite(parent, SWT.NONE); GridLayout mainLayout = new GridLayout(); mainLayout.marginHeight = 0; mainLayout.marginWidth = 0; mainComp.setLayout(mainLayout); GridData gd = new GridData(GridData.FILL_HORIZONTAL); mainComp.setLayoutData(gd); skipDownloadButton = createCheckButton(mainComp, SKIP_DOWNLOAD_BUTTON_TEXT); skipDownloadButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent evt) { updateLaunchConfigurationDialog(); } }); skipDownloadButton.setEnabled(true); } /* * performApply * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply */ public void performApply(ILaunchConfigurationWorkingCopy config) { int currentSelection = connectionCombo.getSelectionIndex(); config.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, currentSelection >= 0 ? connectionCombo .getItem(currentSelection) : null); config.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, remoteProgText.getText()); config .setAttribute( IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, skipDownloadButton.getSelection()); config.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_PRERUN_COMMANDS, preRunText.getText()); super.performApply(config); } /* * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom */ public void initializeFrom(ILaunchConfiguration config) { isInitializing = true; String remoteConnection = null; try { remoteConnection = config .getAttribute( IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, ""); //$NON-NLS-1$ } catch (CoreException ce) { // Ignore } String[] items = connectionCombo.getItems(); int i = 0; for (i = 0; i < items.length; i++) if (items[i].equals(remoteConnection)) break; /* * Select the last used connection in the connecion pulldown if it still * exists. */ if (i < items.length) connectionCombo.select(i); else if (items.length > 0) connectionCombo.select(0); super.initializeFrom(config); updateTargetProgFromConfig(config); updateSkipDownloadFromConfig(config); updatePropertiesButton(); isInitializing = false; } protected void handleNewRemoteConnectionSelected() { if (action == null) { action = new SystemNewConnectionAction(getControl().getShell(), false, false, null); } try { action.run(); } catch (Exception e) { // Ignore } } protected IHost getCurrentConnection() { int currentSelection = connectionCombo.getSelectionIndex(); String remoteConnection = currentSelection >= 0 ? connectionCombo .getItem(currentSelection) : null; return RSEHelper.getRemoteConnectionByName(remoteConnection); } protected void handleRemoteBrowseSelected() { IHost currentConnectionSelected = getCurrentConnection(); SystemRemoteFileDialog dlg = new SystemRemoteFileDialog(getControl() .getShell(), Messages.RemoteCMainTab_Remote_Path_Browse_Button_Title, currentConnectionSelected); dlg.setBlockOnOpen(true); if (dlg.open() == Window.OK) { Object retObj = dlg.getSelectedObject(); if (retObj instanceof IRemoteFile) { IRemoteFile selectedFile = (IRemoteFile) retObj; remoteProgText.setText(selectedFile.getAbsolutePath()); } } } protected void handleRemoteConnectionPropertiesSelected() { class RemoteConnectionPropertyDialog extends Dialog { private IHost fHost; boolean fbLocalHost; private Button fSkipDownloadBtn; private Text fWSRoot; public RemoteConnectionPropertyDialog(Shell parentShell, String dialogTitle, IHost host) { super(parentShell); parentShell.setText(dialogTitle); fHost = host; fbLocalHost = fHost.getSystemType().isLocal(); } protected Control createDialogArea(Composite parent) { // create composite Composite composite = (Composite) super .createDialogArea(parent); Label label = new Label(composite, SWT.WRAP); label.setText(Messages.RemoteCMainTab_Properties_Location); GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER); data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); label.setLayoutData(data); label.setFont(parent.getFont()); fWSRoot = new Text(composite, SWT.SINGLE | SWT.BORDER); fWSRoot.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); fSkipDownloadBtn = new Button(composite, SWT.CHECK); fSkipDownloadBtn .setText(Messages.RemoteCMainTab_Properties_Skip_default); if (!fbLocalHost) { IPropertySet propertySet = fHost .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); if (propertySet != null) { String value = propertySet .getPropertyValue(IRemoteConnectionHostConstants.REMOTE_WS_ROOT); if (value != null) { fWSRoot.setText(value); } fSkipDownloadBtn .setSelection(Boolean .valueOf( propertySet .getPropertyValue(IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD)) .booleanValue()); } } else { fSkipDownloadBtn.setEnabled(false); fWSRoot.setEnabled(false); } applyDialogFont(composite); return composite; } protected void buttonPressed(int buttonId) { if (!fbLocalHost && (buttonId == IDialogConstants.OK_ID)) { IPropertySet propertySet = fHost .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); if (propertySet == null) { propertySet = fHost .createPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); } propertySet.addProperty( IRemoteConnectionHostConstants.REMOTE_WS_ROOT, fWSRoot.getText()); propertySet .addProperty( IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD, Boolean.toString(fSkipDownloadBtn .getSelection())); fHost.commit(); } super.buttonPressed(buttonId); } } IHost currentConnectionSelected = getCurrentConnection(); RemoteConnectionPropertyDialog dlg = new RemoteConnectionPropertyDialog( getControl().getShell(), Messages.RemoteCMainTab_Properties_title, currentConnectionSelected); dlg.setBlockOnOpen(true); dlg.open(); } protected void updateConnectionPulldown() { if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL)) try { RSECorePlugin.waitForInitCompletion(RSECorePlugin.INIT_MODEL); } catch (InterruptedException e) { return; } // already initialized connectionCombo.removeAll(); IHost[] connections = RSEHelper.getSuitableConnections(); for (int i = 0; i < connections.length; i++) { IRSESystemType sysType = connections[i].getSystemType(); if (sysType != null && sysType.isEnabled()) { connectionCombo.add(connections[i].getAliasName()); } } if (connections.length > 0) { connectionCombo.select(connections.length - 1); } updatePropertiesButton(); } private void updatePropertiesButton() { if ((remoteConnectionPropertiesButton == null) || remoteConnectionPropertiesButton.isDisposed()) { return; } boolean bEnableProperties = false; IHost currentConnectionSelected = getCurrentConnection(); if (currentConnectionSelected != null) { IRSESystemType sysType = currentConnectionSelected.getSystemType(); if (sysType != null && sysType.isEnabled() && !sysType.isLocal()) { bEnableProperties = true; } } remoteConnectionPropertiesButton.setEnabled(bEnableProperties); } protected void updateTargetProgFromConfig(ILaunchConfiguration config) { String targetPath = null; try { targetPath = config.getAttribute( IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, REMOTE_PATH_DEFAULT); } catch (CoreException e) { // Ignore } remoteProgText.setText(targetPath); String prelaunchCmd = null; try { prelaunchCmd = config .getAttribute( IRemoteConnectionConfigurationConstants.ATTR_PRERUN_COMMANDS, ""); //$NON-NLS-1$ } catch (CoreException e) { // Ignore } preRunText.setText(prelaunchCmd); } protected void updateSkipDownloadFromConfig(ILaunchConfiguration config) { boolean downloadToTarget = true; try { downloadToTarget = config .getAttribute( IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, getDefaultSkipDownload()); } catch (CoreException e) { // Ignore for now } skipDownloadButton.setSelection(downloadToTarget); } /* * setLocalPathForRemotePath This function sets the remote path text field * with the value of the local executable path. */ private void setLocalPathForRemotePath() { String programName = fProgText.getText().trim(); boolean bUpdateRemote = false; String remoteName = remoteProgText.getText().trim(); String remoteWsRoot = getRemoteWSRoot(); if (remoteName.length() == 0) { bUpdateRemote = true; } else if (remoteWsRoot.length() != 0) { bUpdateRemote = remoteName.equals(remoteWsRoot); } if (programName.length() != 0 && bUpdateRemote) { IProject project = getCProject().getProject(); IPath exePath = new Path(programName); if (!exePath.isAbsolute()) { exePath = project.getFile(programName).getLocation(); IPath wsRoot = project.getWorkspace().getRoot().getLocation(); exePath = makeRelativeToWSRootLocation(exePath, remoteWsRoot, wsRoot); } String path = exePath.toString(); remoteProgText.setText(path); } } private void useDefaultsFromConnection() { // During initialization, we don't want to use the default // values of the connection, but we want to use the ones // that are part of the configuration if (isInitializing) return; if ((remoteProgText != null) && !remoteProgText.isDisposed()) { String remoteName = remoteProgText.getText().trim(); String remoteWsRoot = getRemoteWSRoot(); if (remoteName.length() == 0) { remoteProgText.setText(remoteWsRoot); } else { // try to use remote path IPath wsRoot = getCProject().getProject().getWorkspace() .getRoot().getLocation(); IPath remotePath = makeRelativeToWSRootLocation(new Path( remoteName), remoteWsRoot, wsRoot); remoteProgText.setText(remotePath.toString()); } } if ((skipDownloadButton != null) && !skipDownloadButton.isDisposed()) { skipDownloadButton.setSelection(getDefaultSkipDownload()); if(RSEHelper.getFileSubsystem(getCurrentConnection()) == null){ skipDownloadButton.setEnabled(false); } else { skipDownloadButton.setEnabled(true); } } if((remoteBrowseButton!=null) && !remoteBrowseButton.isDisposed()){ if(RSEHelper.getFileSubsystem(getCurrentConnection()) == null){ remoteBrowseButton.setEnabled(false); } else { remoteBrowseButton.setEnabled(true); } } } private IPath makeRelativeToWSRootLocation(IPath exePath, String remoteWsRoot, IPath wsRoot) { if (remoteWsRoot.length() != 0) { // use remoteWSRoot instead of Workspace Root if (wsRoot.isPrefixOf(exePath)) { return new Path(remoteWsRoot).append(exePath .removeFirstSegments(wsRoot.segmentCount()).setDevice( null)); } } return exePath; } private String getRemoteWSRoot() { IHost host = getCurrentConnection(); if (host != null) { IPropertySet propertySet = host .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); if (propertySet != null) { String value = propertySet .getPropertyValue(IRemoteConnectionHostConstants.REMOTE_WS_ROOT); if (value != null) { return value; } } } return ""; //$NON-NLS-1$ } private boolean getDefaultSkipDownload() { IHost host = getCurrentConnection(); if (host != null) { if(RSEHelper.getFileSubsystem(host) == null){ return true; } IPropertySet propertySet = host .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); if (propertySet != null) { return Boolean .valueOf( propertySet .getPropertyValue(IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD)) .booleanValue(); } } return SKIP_DOWNLOAD_TO_REMOTE_DEFAULT; } @Override public String getId() { return "org.eclipse.rse.remotecdt.launch.RemoteCMainTab"; //$NON-NLS-1$ } }