blob: 64e7dd80daa84f5d3c2f3d72701635decd2c5ec8 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.ndk.internal.launch;
import com.android.ide.eclipse.ndk.internal.NdkHelper;
import com.android.ide.eclipse.ndk.internal.NdkManager;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
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.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class NdkDebuggerTab extends AbstractLaunchConfigurationTab {
private static String sLastGdbPath;
private static String sLastSolibPath;
private Text mGdbPathText;
private Text mGdbInitPathText;
private Text mGdbRemotePortText;
private org.eclipse.swt.widgets.List mSoliblist;
private Button mAddSolibButton;
private Button mDeleteSolibButton;
/**
* @wbp.parser.entryPoint (Window Builder Entry Point)
*/
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
setControl(comp);
comp.setLayout(new GridLayout(1, false));
Group grpGdb = new Group(comp, SWT.NONE);
grpGdb.setText("Launch Options");
grpGdb.setLayout(new GridLayout(3, false));
grpGdb.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Label lblDebugger = new Label(grpGdb, SWT.NONE);
lblDebugger.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblDebugger.setText("Debugger:");
mGdbPathText = new Text(grpGdb, SWT.BORDER);
mGdbPathText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
final Button btnBrowseGdb = new Button(grpGdb, SWT.NONE);
btnBrowseGdb.setText("Browse...");
Label lblNewLabel = new Label(grpGdb, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblNewLabel.setText("GDB Command File:");
mGdbInitPathText = new Text(grpGdb, SWT.BORDER);
mGdbInitPathText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
final Button btnBrowseGdbInit = new Button(grpGdb, SWT.NONE);
btnBrowseGdbInit.setText("Browse...");
SelectionListener browseListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Shell shell = ((Control) e.getSource()).getShell();
if (e.getSource() == btnBrowseGdb) {
browseForGdb(shell);
} else {
browseForGdbInit(shell);
}
checkParameters();
updateLaunchConfigurationDialog();
}
};
btnBrowseGdb.addSelectionListener(browseListener);
btnBrowseGdbInit.addSelectionListener(browseListener);
Label lblPort = new Label(grpGdb, SWT.NONE);
lblPort.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblPort.setText("Port:");
mGdbRemotePortText = new Text(grpGdb, SWT.BORDER);
GridData gd_text_2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_text_2.widthHint = 100;
mGdbRemotePortText.setLayoutData(gd_text_2);
ModifyListener m = new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
checkParameters();
updateLaunchConfigurationDialog();
}
};
mGdbPathText.addModifyListener(m);
mGdbInitPathText.addModifyListener(m);
mGdbRemotePortText.addModifyListener(m);
Group grpSharedLibraries = new Group(comp, SWT.NONE);
grpSharedLibraries.setText("Shared Libraries");
grpSharedLibraries.setLayout(new GridLayout(2, false));
GridData gd_grpSharedLibraries = new GridData(GridData.FILL_BOTH);
gd_grpSharedLibraries.verticalAlignment = SWT.TOP;
gd_grpSharedLibraries.grabExcessVerticalSpace = true;
grpSharedLibraries.setLayoutData(gd_grpSharedLibraries);
mSoliblist = new org.eclipse.swt.widgets.List(grpSharedLibraries,
SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE);
GridData gd_list = new GridData(GridData.FILL_BOTH);
gd_list.heightHint = 133;
gd_list.grabExcessVerticalSpace = false;
gd_list.verticalSpan = 1;
mSoliblist.setLayoutData(gd_list);
Composite composite = new Composite(grpSharedLibraries, SWT.NONE);
composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
composite.setLayout(new RowLayout(SWT.VERTICAL));
mAddSolibButton = new Button(composite, SWT.NONE);
mAddSolibButton.setText("Add...");
mDeleteSolibButton = new Button(composite, SWT.NONE);
mDeleteSolibButton.setText("Remove");
mDeleteSolibButton.setEnabled(false);
SelectionListener l = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Control c = (Control) e.getSource();
if (c == mSoliblist) {
// enable delete only if there is a selection
mDeleteSolibButton.setEnabled(mSoliblist.getSelectionCount() > 0);
} else if (c == mAddSolibButton) {
addSolib(c.getShell());
} else {
// delete current selection
int index = mSoliblist.getSelectionIndex();
if (index >= 0) {
mSoliblist.remove(index);
}
}
updateLaunchConfigurationDialog();
}
};
mSoliblist.addSelectionListener(l);
mAddSolibButton.addSelectionListener(l);
mDeleteSolibButton.addSelectionListener(l);
}
private void addSolib(Shell shell) {
DirectoryDialog dd = new DirectoryDialog(shell);
if (sLastSolibPath != null) {
dd.setFilterPath(sLastSolibPath);
}
String solibPath = dd.open();
if (solibPath != null) {
mSoliblist.add(solibPath);
sLastSolibPath = new File(solibPath).getParent();
}
}
private void browseForGdb(Shell shell) {
if (sLastGdbPath == null) {
sLastGdbPath = NdkManager.getNdkLocation();
}
FileDialog fd = new FileDialog(shell);
fd.setFilterPath(sLastGdbPath);
String gdbPath = fd.open();
if (gdbPath != null) {
mGdbPathText.setText(gdbPath);
sLastGdbPath = new File(gdbPath).getParent();
}
}
private void browseForGdbInit(Shell shell) {
FileDialog fd = new FileDialog(shell);
String gdbInit = fd.open();
if (gdbInit != null) {
mGdbInitPathText.setText(gdbInit);
}
}
private void checkParameters() {
// check gdb path
String gdb = mGdbPathText.getText().trim();
if (!gdb.equals(NdkLaunchConstants.DEFAULT_GDB)) {
File f = new File(gdb);
if (!f.exists() || !f.canExecute()) {
setErrorMessage("Invalid gdb location.");
return;
}
}
// check gdb init path
String gdbInit = mGdbInitPathText.getText().trim();
if (!gdbInit.isEmpty()) {
File f = new File(gdbInit);
if (!f.exists() || !f.isFile()) {
setErrorMessage("Invalid gdbinit location.");
return;
}
}
// port should be a valid integer
String port = mGdbRemotePortText.getText().trim();
try {
Integer.parseInt(port, 10);
} catch (NumberFormatException e) {
setErrorMessage("Port should be a valid integer");
return;
}
// no errors
setErrorMessage(null);
setMessage(null);
}
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
NdkHelper.setLaunchConfigDefaults(config);
}
@Override
public void initializeFrom(ILaunchConfiguration config) {
mGdbPathText.setText(getAttribute(config, NdkLaunchConstants.ATTR_NDK_GDB,
NdkLaunchConstants.DEFAULT_GDB));
mGdbInitPathText.setText(getAttribute(config,
IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
NdkLaunchConstants.DEFAULT_GDBINIT));
mGdbRemotePortText.setText(getAttribute(config, IGDBLaunchConfigurationConstants.ATTR_PORT,
NdkLaunchConstants.DEFAULT_GDB_PORT));
List<String> solibs = getAttribute(config, NdkLaunchConstants.ATTR_NDK_SOLIB,
Collections.EMPTY_LIST);
mSoliblist.removeAll();
for (String s: solibs) {
mSoliblist.add(s);
}
}
private String getAttribute(ILaunchConfiguration config, String key, String defaultValue) {
try {
return config.getAttribute(key, defaultValue);
} catch (CoreException e) {
return defaultValue;
}
}
private List<String> getAttribute(ILaunchConfiguration config, String key,
List<String> defaultValue) {
try {
return config.getAttribute(key, defaultValue);
} catch (CoreException e) {
return defaultValue;
}
}
@Override
public void performApply(ILaunchConfigurationWorkingCopy config) {
config.setAttribute(NdkLaunchConstants.ATTR_NDK_GDB, mGdbPathText.getText().trim());
config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
mGdbInitPathText.getText().trim());
config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT,
mGdbRemotePortText.getText().trim());
config.setAttribute(NdkLaunchConstants.ATTR_NDK_SOLIB,
Arrays.asList(mSoliblist.getItems()));
}
@Override
public String getName() {
return "Debugger";
}
}