/*******************************************************************************
* Copyright (c) 2008, 2011 Thomas Holland (thomas@innot.de) 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:
* Thomas Holland - initial API and implementation
*******************************************************************************/
package de.innot.avreclipse.debug.ui;
import java.io.File;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.gdbjtag.core.IGDBJtagConstants;
import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants;
import org.eclipse.cdt.debug.mi.core.MIPlugin;
import org.eclipse.cdt.debug.mi.core.command.factories.CommandFactoryDescriptor;
import org.eclipse.cdt.debug.mi.core.command.factories.CommandFactoryManager;
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.debug.ui.StringVariableSelectionDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import de.innot.avreclipse.debug.core.IAVRGDBConstants;
/**
* The LaunchConfigurationTab for general settings of the debugger
*
* @author Thomas Holland
* @since 2.4
*
*/
public class TabDebugger extends AbstractLaunchConfigurationTab implements IAVRGDBConstants,
IMILaunchConfigurationConstants, IGdbJtagMapper {
private static final String TAB_NAME = "Debugger";
// The GUI Elements
private Text fAVRGDBCommand;
private Button fVerboseMode;
private Button fStopInMain;
private Text fStopInMainSymbol;
private Button fResume;
/*
* (non-Javadoc)
* @seeorg.eclipse.debug.ui.AbstractLaunchConfigurationTab#activated(org.eclipse.debug.core.
* ILaunchConfigurationWorkingCopy)
*/
@Override
public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
// TODO Auto-generated method stub
super.activated(workingCopy);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
*/
public String getName() {
return TAB_NAME;
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getImage()
*/
@Override
public Image getImage() {
return AVRGDBImages.getImage(AVRGDBImages.TAB_DEBUGGER_IMG);
}
/*
* (non-Javadoc)
* @seeorg.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.
* ILaunchConfiguration)
*/
public void initializeFrom(ILaunchConfiguration configuration) {
try {
String gdbCommandAttr = configuration.getAttribute(ATTR_DEBUG_NAME,
DEFAULT_COMMAND_NAME);
fAVRGDBCommand.setText(gdbCommandAttr);
boolean verboseModeAttr = configuration.getAttribute(ATTR_DEBUGGER_VERBOSE_MODE,
DEFAULT_VERBOSE_MODE);
fVerboseMode.setSelection(verboseModeAttr);
fStopInMain.setSelection(configuration.getAttribute(IGDBJtagConstants.ATTR_SET_STOP_AT,
IGDBJtagConstants.DEFAULT_SET_STOP_AT));
fStopInMainSymbol.setText(configuration.getAttribute(IGDBJtagConstants.ATTR_STOP_AT,
IGDBJtagConstants.DEFAULT_STOP_AT));
fResume.setSelection(configuration.getAttribute(ATTR_SET_RESUME,
DEFAULT_SET_RESUME));
} catch (CoreException e) {
AVRGDBUIPlugin.log(e.getStatus());
}
}
/*
* (non-Javadoc)
* @seeorg.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.
* ILaunchConfigurationWorkingCopy)
*/
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(ATTR_DEBUG_NAME, fAVRGDBCommand.getText().trim());
// GDB base plugin doesn't use default name, sigh
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, fAVRGDBCommand.getText().trim());
configuration.setAttribute(ATTR_DEBUGGER_COMMAND_FACTORY, DEFAULT_COMMAND_FACTORY);
configuration.setAttribute(ATTR_DEBUGGER_PROTOCOL, DEFAULT_DEBUGGER_PROTOCOL);
configuration.setAttribute(ATTR_DEBUGGER_VERBOSE_MODE, fVerboseMode.getSelection());
configuration.setAttribute(IGDBJtagConstants.ATTR_SET_STOP_AT, fStopInMain.getSelection());
configuration.setAttribute(IGDBJtagConstants.ATTR_STOP_AT, fStopInMainSymbol.getText());
configuration.setAttribute(ATTR_SET_RESUME, fResume.getSelection());
updateGdbJagAttributes(configuration);
}
@Override
public void updateGdbJagAttributes
(ILaunchConfigurationWorkingCopy configuration) {
// Settings for the GdbJtagFinalInitialization
configuration.setAttribute
(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS, true);
configuration.setAttribute
(IGDBJtagConstants.ATTR_LOAD_IMAGE, false);
configuration.setAttribute
(IGDBJtagConstants.ATTR_DO_RESET, false);
configuration.setAttribute(IGDBJtagConstants.ATTR_DO_RESET, false);
try {
configuration.setAttribute(IGDBJtagConstants.ATTR_SET_RESUME,
configuration.getAttribute(ATTR_SET_RESUME, DEFAULT_SET_RESUME));
} catch (CoreException e) {
AVRGDBUIPlugin.log(e.getStatus());
}
}
public boolean isValid(ILaunchConfiguration config) {
if (fStopInMain != null && fStopInMainSymbol != null) {
// The "Stop on startup at" field must not be empty
String mainSymbol = fStopInMainSymbol.getText().trim();
if (fStopInMain.getSelection() && mainSymbol.length() == 0) {
setErrorMessage("The \"Stop on startup at\" field must not be empty");
return false;
}
}
if (super.isValid(config) == false) {
return false;
}
return true;
}
/*
* (non-Javadoc)
* @seeorg.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.
* ILaunchConfigurationWorkingCopy)
*/
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(ATTR_DEBUG_NAME, DEFAULT_COMMAND_NAME);
// GDB base plugin doesn't use default name, sigh
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, DEFAULT_COMMAND_NAME);
CommandFactoryManager cfManager = MIPlugin.getDefault().getCommandFactoryManager();
CommandFactoryDescriptor defDesc = cfManager.getDefaultDescriptor(DEBUGGER_ID);
configuration.setAttribute(ATTR_DEBUGGER_COMMAND_FACTORY, defDesc.getName());
configuration.setAttribute(ATTR_DEBUGGER_PROTOCOL, defDesc.getMIVersions()[0]);
configuration.setAttribute(ATTR_DEBUGGER_VERBOSE_MODE, DEFAULT_VERBOSE_MODE);
configuration.setAttribute(IGDBJtagConstants.ATTR_SET_STOP_AT, true);
configuration.setAttribute(IGDBJtagConstants.ATTR_STOP_AT, "main");
configuration.setAttribute(ATTR_SET_RESUME, DEFAULT_SET_RESUME);
updateGdbJagAttributes(configuration);
}
/*
* (non-Javadoc)
* @see
* org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
setControl(comp);
// PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
// IDebugHelpContextIds.SOURCELOOKUP_TAB);
GridLayout topLayout = new GridLayout();
// topLayout.marginWidth = 0;
// topLayout.marginHeight = 0;
// topLayout.numColumns = 1;
comp.setLayout(topLayout);
comp.setFont(parent.getFont());
// Composite comp = new Composite(sc, SWT.NONE);
// comp.setLayout(new GridLayout());
// sc.setContent(comp);
createCommandGroup(comp);
createOptionGroup(comp);
}
/**
* Add the "GDB Setup" group to the parent composite.
*
* @param parent
*/
private void createCommandGroup(Composite parent) {
Group group = new Group(parent, SWT.NONE);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
group.setLayout(new GridLayout());
group.setText("GDB Setup");
// /////////////////////////////////////////////////////////
//
// The "AVR GDB command" option
//
// /////////////////////////////////////////////////////////
Composite commandComp = new Composite(group, SWT.NONE);
commandComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
commandComp.setLayout(new GridLayout(3, false));
Label label = new Label(commandComp, SWT.NONE);
label.setText("AVR GDB command:");
label.setLayoutData(new GridData(SWT.BEGINNING, SWT.NONE, false, false, 3, 1));
fAVRGDBCommand = new Text(commandComp, SWT.SINGLE | SWT.BORDER);
fAVRGDBCommand.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
fAVRGDBCommand.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
updateLaunchConfigurationDialog();
}
});
Button button = new Button(commandComp, SWT.NONE);
button.setText("Browse...");
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
browseButtonAction("Select AVR GDB Binary", fAVRGDBCommand);
}
});
button = new Button(commandComp, SWT.NONE);
button.setText("Variables...");
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
variablesButtonAction(fAVRGDBCommand);
}
});
// /////////////////////////////////////////////////////////
//
// The "Verbose console mode" option
//
// /////////////////////////////////////////////////////////
fVerboseMode = new Button(commandComp, SWT.CHECK);
fVerboseMode.setText("Verbose console mode");
fVerboseMode.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
}
/**
* Add the "Runtime Options" group to the parent composite.
*
* @param parent
*/
private void createOptionGroup(Composite parent) {
Group group = new Group(parent, SWT.NONE);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
group.setLayout(new GridLayout());
group.setText("Runtime Options");
Composite optComp = new Composite(group, SWT.NONE);
optComp.setLayout(new GridLayout(2, false));
fStopInMain = createCheckButton(optComp, "Stop on startup at:");
fStopInMain.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
fStopInMainSymbol.setEnabled(fStopInMain.getSelection());
updateLaunchConfigurationDialog();
}
});
fStopInMainSymbol = new Text(optComp, SWT.SINGLE | SWT.BORDER);
final GridData gridData = new GridData(GridData.FILL, GridData.CENTER, false, false);
gridData.widthHint = 100;
fStopInMainSymbol.setLayoutData(gridData);
fStopInMainSymbol.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent evt) {
updateLaunchConfigurationDialog();
}
});
fStopInMainSymbol.getAccessible().addAccessibleListener(
new AccessibleAdapter() {
public void getName(AccessibleEvent e) {
e.result = "Stop on startup at:";
}
}
);
optComp = new Composite(group, SWT.NONE);
optComp.setLayout(new GridLayout());
fResume = createCheckButton(optComp, "Resume");
fResume.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
}
/**
* Open a file dialog with the given title and for the given <code>Text</code> Control.
* <p>
* If the user selects a new file then the full path of the file will written to the
* <code>Text</code> control value. If the user cancels the dialog, then the <code>Text</code>
* control is untouched.
* </p>
*
* @param title
* Dialog title string
* @param text
* The <code>Text</code> control to be modified
*/
private void browseButtonAction(String title, Text text) {
FileDialog dialog = new FileDialog(getShell(), SWT.NONE);
dialog.setText(title);
// Check if the previously entered commandname contains a path segment
File commandfile = new File(text.getText().trim());
String commandfilepath = commandfile.getParent();
if (commandfilepath != null) {
dialog.setFilterPath(commandfilepath);
}
String newcommand = dialog.open();
if (newcommand != null)
text.setText(newcommand);
}
/**
* Open a variables browser dialog and append the selected variable to the content of the given
* <code>Text</code> control.
*
* @param text
* The <code>Text</code> control to be modified
*/
private void variablesButtonAction(Text text) {
StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell());
dialog.open();
text.append(dialog.getVariableExpression());
}
/**
* Enable / Disable the given Composite.
*
* @param compo
* A <code>Composite</code> with some controls.
* @param value
* <code>true</code> to enable, <code>false</code> to disable the given group.
*/
protected void setEnabled(Composite compo, boolean value) {
Control[] children = compo.getChildren();
for (Control child : children) {
child.setEnabled(value);
}
}
}