| /* |
| * 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"; |
| } |
| } |