diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF
index 304d3a8ba87..862bec2a3e0 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF
@@ -29,6 +29,7 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui.actions;x-internal:=true,
org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints;x-internal:=true,
org.eclipse.cdt.dsf.gdb.internal.ui.launching;x-internal:=true,
+ org.eclipse.cdt.dsf.gdb.internal.ui.tracepointactions;x-internal:=true,
org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;x-internal:=true,
org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch;x-internal:=true
Import-Package: com.ibm.icu.text
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties
index 923aef3f505..39b4f084eef 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties
@@ -30,6 +30,8 @@ editorTextHover.description=Shows formatted value in debugger hover
breakpoints.property.filter=Filter
tracepoints.property.common=Common
tracepoints.property.actions=Actions
+tracepoints.action.page.label=Actions
+tracepointActionsPrefPage.name=Tracepoint Actions
popup.addExpression.label=Add Watch Expression...
popup.resumeAtLine.label=Resume At Li&ne
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml
index 74b85610460..53dee121099 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml
@@ -389,6 +389,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
tracepointActions;
+ private IBreakpointActionPage[] actionPages;
+ private String actionName;
+ private Text actionNameTextWidget;
+ private Combo combo;
+ private Composite dialogArea;
+ private int lastSelectedActionTypeIndex;
+ private IBreakpointAction originalAction;
+ private boolean isSubAction;
+
+ private IExtension[] breakpointActionPageExtensions;
+
+ /**
+ * Create the dialog
+ */
+ public TracepointActionDialog(Shell parentShell, ITracepointAction action, boolean isSub) {
+ super(parentShell);
+ setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
+ originalAction = action;
+ tracepointAction = action;
+ lastSelectedActionTypeIndex = 0;
+ isSubAction = isSub;
+ }
+
+ @Override
+ protected void cancelPressed() {
+ actionPage.actionDialogCanceled();
+ super.cancelPressed();
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ if (originalAction == null)
+ newShell.setText(MessagesForTracepointActions.TracepointActions_ActionDialog_New);
+ else
+ newShell.setText(originalAction.getName());
+ }
+
+ /**
+ * Create contents of the button bar
+ */
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ /**
+ * Create contents of the dialog
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ dialogArea = (Composite) super.createDialogArea(parent);
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ dialogArea.setLayout(gridLayout);
+
+ final Label actionNameLabel = new Label(dialogArea, SWT.NONE);
+ actionNameLabel.setText(MessagesForTracepointActions.TracepointActions_ActionDialog_Name);
+
+ actionNameTextWidget = new Text(dialogArea, SWT.BORDER);
+ actionNameTextWidget.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ final Label breakpointActionTypeLabel = new Label(dialogArea, SWT.NONE);
+ breakpointActionTypeLabel.setText(MessagesForTracepointActions.TracepointActions_ActionDialog_Type);
+
+ combo = new Combo(dialogArea, SWT.READ_ONLY);
+ combo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ try {
+ showActionComposite();
+ } catch (CoreException e1) {
+ }
+ }
+ });
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ tracepointActions = new Vector(TRACEPOINT_ACTIONS_COUNT);
+ tracepointActions.add(new CollectAction());
+ tracepointActions.add(new EvaluateAction());
+ // Sub actions of whileStepping cannot be whileStepping
+ if (!isSubAction) tracepointActions.add(new WhileSteppingAction());
+
+ actionPages = new IBreakpointActionPage[TRACEPOINT_ACTIONS_COUNT];
+ actionComposites = new Composite[TRACEPOINT_ACTIONS_COUNT];
+
+ if (tracepointActions.size() > 0) {
+
+ String lastTypeName = GdbUIPlugin.getDefault().getPreferenceStore().getString(TRACEPOINT_ACTION_DIALOG_LAST_SELECTED);
+
+ if (tracepointAction != null) {
+ lastTypeName = tracepointAction.getTypeName();
+ actionName = tracepointAction.getName();
+ }
+
+ for (int i = 0; i < tracepointActions.size(); i++) {
+ tracepointActions.get(i).setName(tracepointActions.get(i).getDefaultName());
+ String actionTypeName = tracepointActions.get(i).getTypeName();
+ combo.add(actionTypeName);
+ if (actionTypeName.equals(lastTypeName)) {
+ lastSelectedActionTypeIndex = i;
+ if (tracepointAction != null) {
+ tracepointActions.add(i, tracepointAction);
+ tracepointActions.remove(i+1);
+ }
+ }
+ }
+
+ combo.select(lastSelectedActionTypeIndex);
+ if (originalAction != null)
+ combo.setEnabled(false);
+
+ actionArea = new Composite(dialogArea, SWT.NONE);
+ actionArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+ actionArea.setLayout(new StackLayout());
+ try {
+ showActionComposite();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return dialogArea;
+ }
+
+ public IBreakpointAction getTracepointAction() {
+ return tracepointAction;
+ }
+
+ public String getActionName() {
+ return actionName;
+ }
+
+ /**
+ * Return the initial size of the dialog
+ */
+ @Override
+ protected Point getInitialSize() {
+ return new Point(500, 375);
+ }
+
+ @Override
+ protected void okPressed() {
+ if (originalAction == null)
+ GdbUIPlugin.getDefault().getPreferenceStore().setValue(TRACEPOINT_ACTION_DIALOG_LAST_SELECTED, tracepointAction.getTypeName());
+ String newName = actionNameTextWidget.getText();
+ if (originalAction == null || !originalAction.getName().equals(newName)) {
+ actionName = TracepointActionManager.getInstance().makeUniqueActionName(newName);
+ tracepointAction.setName(actionName);
+ }
+ actionPage.actionDialogOK();
+ super.okPressed();
+ }
+
+ void showActionComposite() throws CoreException {
+ // Find the selected extension
+ int selectedTypeIndex = combo.getSelectionIndex();
+ lastSelectedActionTypeIndex = selectedTypeIndex;
+ tracepointAction = tracepointActions.get(selectedTypeIndex);
+
+ actionPage = actionPages[selectedTypeIndex];
+ if (actionPage == null) {
+ actionPages[selectedTypeIndex] = getActionPage(tracepointActions.get(selectedTypeIndex));
+ actionPage = actionPages[selectedTypeIndex];
+ }
+ if (actionComposites[selectedTypeIndex] == null) {
+ Composite actionComposite = actionPages[selectedTypeIndex].createComposite(tracepointAction, actionArea, SWT.NONE);
+ actionComposites[selectedTypeIndex] = actionComposite;
+ }
+ actionName = tracepointAction.getName();
+
+ actionNameTextWidget.setText(actionName);
+ StackLayout stacklayout = (StackLayout) actionArea.getLayout();
+ stacklayout.topControl = actionComposites[selectedTypeIndex];
+ actionArea.layout();
+ }
+
+ public IExtension[] getBreakpointActionPageExtensions() {
+ if (breakpointActionPageExtensions == null) {
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CDebugUIPlugin.PLUGIN_ID, BREAKPOINT_ACTION_PAGE_EXTENSION_POINT_ID);
+ if (point == null)
+ breakpointActionPageExtensions = new IExtension[0];
+ else {
+ breakpointActionPageExtensions = point.getExtensions();
+ }
+ }
+
+ return breakpointActionPageExtensions;
+ }
+
+ private IBreakpointActionPage getActionPage(IBreakpointAction breakpointAction) {
+ IExtension[] actionExtensions = getBreakpointActionPageExtensions();
+
+ IBreakpointActionPage actionPageResult = null;
+ try {
+
+ for (int i = 0; i < actionExtensions.length && actionPageResult == null; i++) {
+ IConfigurationElement[] elements = actionExtensions[i].getConfigurationElements();
+ for (int j = 0; j < elements.length && actionPageResult == null; j++) {
+ IConfigurationElement element = elements[j];
+ if (element.getName().equals(ACTION_PAGE_ELEMENT)) {
+ if (element.getAttribute("actionType").equals(breakpointAction.getIdentifier())) { //$NON-NLS-1$
+ actionPageResult = (IBreakpointActionPage) element.createExecutableExtension("class"); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ } catch (CoreException e) {
+ }
+ return actionPageResult;
+ }
+
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsList.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsList.java
new file mode 100644
index 00000000000..be64807ef76
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsList.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Nokia 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:
+ * Nokia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.tracepointactions;
+
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager;
+import org.eclipse.swt.SWT;
+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.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * @since 2.1
+ */
+public class TracepointActionsList extends Composite {
+
+ private Button removeButton;
+ private Button upButton;
+ private Button downButton;
+ private Table table;
+
+ public TracepointActionsList(Composite parent, int style) {
+ super(parent, style);
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 4;
+ setLayout(gridLayout);
+
+ table = new Table(this, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);
+ final GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+ gridData.heightHint = 60;
+ gridData.horizontalSpan = 4;
+ table.setLayoutData(gridData);
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+ table.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateButtons();
+ }
+ });
+
+ final TableColumn nameTableColumn = new TableColumn(table, SWT.NONE);
+ nameTableColumn.setWidth(120);
+ nameTableColumn.setText(MessagesForTracepointActions.TracepointActions_Name);
+
+ final TableColumn typeTableColumn = new TableColumn(table, SWT.NONE);
+ typeTableColumn.setWidth(120);
+ typeTableColumn.setText(MessagesForTracepointActions.TracepointActions_Type);
+
+ final TableColumn summaryTableColumn = new TableColumn(table, SWT.NONE);
+ summaryTableColumn.setWidth(120);
+ summaryTableColumn.setText(MessagesForTracepointActions.TracepointActions_Summary);
+
+ removeButton = new Button(this, SWT.NONE);
+ removeButton.setText(MessagesForTracepointActions.TracepointActions_Remove);
+
+ removeButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ HandleRemoveButton();
+ }
+ });
+
+ upButton = new Button(this, SWT.NONE);
+ upButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ HandleUpButton();
+ }
+ });
+ upButton.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END));
+ upButton.setText(MessagesForTracepointActions.TracepointActions_Up);
+
+ downButton = new Button(this, SWT.NONE);
+ downButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ HandleDownButton();
+ }
+ });
+ downButton.setText(MessagesForTracepointActions.TracepointActions_Down);
+
+ updateButtons();
+ }
+
+ public void addAction(ITracepointAction action) {
+ TableItem[] currentItems = table.getItems();
+ boolean alreadyInList = false;
+ for (TableItem currentItem : currentItems) {
+ if (((ITracepointAction) currentItem.getData()).equals(action)) {
+ alreadyInList = true;
+ break;
+ }
+ }
+ if (!alreadyInList) {
+ final TableItem tableItem = new TableItem(table, SWT.NONE);
+ tableItem.setText(0, action.getName());
+ tableItem.setText(1, action.getTypeName());
+ tableItem.setText(2, action.getSummary());
+ tableItem.setData(action);
+ }
+ updateButtons();
+ }
+
+ public void removeAction(ITracepointAction action) {
+ TableItem[] currentItems = table.getItems();
+ for (int i = 0; i < currentItems.length; i++) {
+ if (((ITracepointAction) currentItems[i].getData()).equals(action)) {
+ table.remove(i);
+ break;
+ }
+ }
+ updateButtons();
+ }
+
+ public String getActionNames() {
+ StringBuffer result = new StringBuffer();
+ TableItem[] currentItems = table.getItems();
+ for (int i = 0; i < currentItems.length; i++) {
+ if (i > 0) {
+ result.append(',');
+ }
+ result.append(((ITracepointAction) currentItems[i].getData()).getName());
+ }
+ return result.toString();
+ }
+
+ private void swapItems(TableItem item, TableItem item2) {
+ String[] item2Text = { item2.getText(0), item2.getText(1), item2.getText(2) };
+ Object item2Data = item2.getData();
+
+ item2.setText(0, item.getText(0));
+ item2.setText(1, item.getText(1));
+ item2.setText(2, item.getText(2));
+ item2.setData(item.getData());
+
+ item.setText(0, item2Text[0]);
+ item.setText(1, item2Text[1]);
+ item.setText(2, item2Text[2]);
+ item.setData(item2Data);
+ }
+
+ protected void HandleUpButton() {
+ int[] selection = table.getSelectionIndices();
+ if (selection.length == 1 && selection[0] > 0) {
+ swapItems(table.getItem(selection[0]), table.getItem(selection[0] - 1));
+ }
+ }
+
+ protected void HandleDownButton() {
+ int[] selection = table.getSelectionIndices();
+ if (selection.length == 1 && selection[0] < (table.getItemCount() - 1)) {
+ swapItems(table.getItem(selection[0]), table.getItem(selection[0] + 1));
+ }
+ }
+
+ protected void HandleRemoveButton() {
+ table.remove(table.getSelectionIndices());
+ if (table.getItemCount() > 0) {
+ table.select(table.getItemCount() - 1);
+ }
+ updateButtons();
+ }
+
+ public void setNames(String actionNames) {
+
+ table.removeAll();
+ String[] names = actionNames.split(","); //$NON-NLS-1$
+
+ for (String actionName : names) {
+ ITracepointAction action = TracepointActionManager.getInstance().findAction(actionName);
+ if (action != null) {
+ final TableItem tableItem = new TableItem(table, SWT.NONE);
+ tableItem.setText(0, action.getName());
+ tableItem.setText(1, action.getTypeName());
+ tableItem.setText(2, action.getSummary());
+ tableItem.setData(action);
+ }
+ }
+
+ updateButtons();
+ }
+
+ public void updateButtons() {
+ int[] selectedItems = table.getSelectionIndices();
+ removeButton.setEnabled(selectedItems.length > 0);
+ downButton.setEnabled(selectedItems.length == 1 && selectedItems[0] < (table.getItemCount() - 1));
+ upButton.setEnabled(selectedItems.length == 1 && selectedItems[0] > 0);
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPreferencePage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPreferencePage.java
new file mode 100644
index 00000000000..14ec554e78c
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPreferencePage.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Nokia 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:
+ * Nokia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.tracepointactions;
+
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager;
+import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @since 2.1
+ */
+public class TracepointActionsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private String contextHelpID = "tracepoint_actions_page_help"; //$NON-NLS-1$
+
+ public TracepointActionsPreferencePage() {
+ super();
+ setPreferenceStore(GdbUIPlugin.getDefault().getPreferenceStore());
+ }
+
+ @Override
+ public Control createContents(Composite parent) {
+ Composite container = new Composite(parent, SWT.NONE);
+ final GridLayout gridLayout = new GridLayout();
+ container.setLayout(gridLayout);
+
+ final Label breakpointActionsAvailableLabel = new Label(container, SWT.NONE);
+ breakpointActionsAvailableLabel.setText(MessagesForTracepointActions.TracepointActions_Preferences_Actions_Available);
+ final TracepointGlobalActionsList actionsList = new TracepointGlobalActionsList(container, SWT.NONE, false, false);
+ actionsList.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+
+ String helpContextID = GdbUIPlugin.PLUGIN_ID + "." + contextHelpID; //$NON-NLS-1$
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(super.getControl(), helpContextID);
+
+ return container;
+ }
+
+ public void init(IWorkbench workbench) {
+ }
+
+ @Override
+ public boolean performCancel() {
+ TracepointActionManager.getInstance().revertActionData();
+ return super.performCancel();
+ }
+
+ @Override
+ public boolean performOk() {
+ TracepointActionManager.getInstance().saveActionData();
+ return super.performOk();
+ }
+
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPropertyPage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPropertyPage.java
new file mode 100644
index 00000000000..8e9e19c1692
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPropertyPage.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Nokia 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:
+ * Nokia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.tracepointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.BreakpointActionManager;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.swt.SWT;
+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.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+/**
+ * Property page for Tracepoint actions
+ *
+ * @since 2.1
+ */
+public class TracepointActionsPropertyPage extends PropertyPage {
+
+ private TracepointActionsList actionsList;
+ private IMarker tracepointMarker;
+ private TracepointGlobalActionsList globalActionsList;
+ private String savedActionNames;
+
+ public TracepointActionsPropertyPage() {
+ super();
+ }
+
+ @Override
+ public Control createContents(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+
+ IBreakpoint tracepoint = (IBreakpoint) this.getElement().getAdapter(org.eclipse.debug.core.model.IBreakpoint.class);
+ tracepointMarker = tracepoint.getMarker();
+ savedActionNames = tracepointMarker.getAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$
+
+ final Label actionsTriggeredWhenLabel = new Label(container, SWT.NONE);
+ final GridData gridData_2 = new GridData();
+ gridData_2.horizontalSpan = 2;
+ actionsTriggeredWhenLabel.setLayoutData(gridData_2);
+ actionsTriggeredWhenLabel.setText(MessagesForTracepointActions.TracepointActions_Actions_for_this_tracepoint);
+
+ actionsList = new TracepointActionsList(container, SWT.NONE);
+ final GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+ gridData.horizontalSpan = 2;
+ actionsList.setLayoutData(gridData);
+
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ container.setLayout(gridLayout);
+
+ final Label label = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
+ final GridData gridData_4 = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ gridData_4.horizontalSpan = 2;
+ label.setLayoutData(gridData_4);
+
+ final Label allAvailableActionsLabel = new Label(container, SWT.NONE);
+ final GridData gridData_3 = new GridData();
+ gridData_3.horizontalSpan = 2;
+ allAvailableActionsLabel.setLayoutData(gridData_3);
+ allAvailableActionsLabel.setText(MessagesForTracepointActions.TracepointActions_Available_actions);
+
+ globalActionsList = new TracepointGlobalActionsList(container, SWT.NONE, true, false);
+ final GridData gridData_1 = new GridData(GridData.FILL_BOTH);
+ gridData_1.horizontalSpan = 2;
+ globalActionsList.setLayoutData(gridData_1);
+
+ String actionNames = tracepointMarker.getAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$
+ actionsList.setNames(actionNames);
+
+ globalActionsList.getAttachButton().addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ HandleAttachButton();
+ }
+ });
+
+ globalActionsList.getDeleteButton().addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ HandleDeleteButton();
+ }
+ });
+
+ return container;
+ }
+
+ protected void HandleAttachButton() {
+
+ ITracepointAction[] selectedActions = globalActionsList.getSelectedActions();
+ for (int i = 0; i < selectedActions.length; i++) {
+ actionsList.addAction(selectedActions[i]);
+ }
+ }
+
+ /**
+ * Clean up attached actions that were just deleted from the GlobalActionList
+ *
+ * @since 7.0
+ */
+ protected void HandleDeleteButton() {
+
+ // First remove any attached action that was just deleted
+ ITracepointAction[] selectedActions = globalActionsList.getSelectedActions();
+ for (int i = 0; i < selectedActions.length; i++) {
+ actionsList.removeAction(selectedActions[i]);
+ }
+ // Now cleanup the global action list
+ globalActionsList.HandleDeleteButton();
+ }
+
+ @Override
+ protected void performDefaults() {
+ try {
+ tracepointMarker.setAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$
+ actionsList.setNames(""); //$NON-NLS-1$
+ } catch (CoreException e) {
+ }
+ super.performDefaults();
+ }
+
+ @Override
+ public boolean performCancel() {
+ try {
+ tracepointMarker.setAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, savedActionNames);
+ TracepointActionManager.getInstance().revertActionData();
+ } catch (CoreException e) {
+ }
+ return super.performCancel();
+ }
+
+ @Override
+ public boolean performOk() {
+ try {
+ TracepointActionManager.getInstance().saveActionData();
+ tracepointMarker.setAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, actionsList.getActionNames());
+ } catch (CoreException e) {
+ }
+ return super.performOk();
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointGlobalActionsList.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointGlobalActionsList.java
new file mode 100644
index 00000000000..ea0ac50e32b
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointGlobalActionsList.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.tracepointactions;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.WhileSteppingAction;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+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.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * @since 2.1
+ */
+public class TracepointGlobalActionsList extends Composite {
+
+ private Button attachButton;
+ private Button deleteButton;
+ private Button editButton;
+ private Button newButton;
+ private Table table;
+ private boolean isSubAction;
+
+ public TracepointGlobalActionsList(Composite parent, int style, boolean useAttachButton, boolean isSub) {
+ super(parent, style);
+ isSubAction = isSub;
+
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 5;
+ setLayout(gridLayout);
+
+ table = new Table(this, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
+ table.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ HandleEditButton();
+ }
+ });
+
+ final GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.horizontalSpan = 5;
+ table.setLayoutData(gridData);
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+
+ final TableColumn nameTableColumn = new TableColumn(table, SWT.NONE);
+ nameTableColumn.setWidth(120);
+ nameTableColumn.setText(MessagesForTracepointActions.TracepointActions_Name);
+
+ final TableColumn typeTableColumn = new TableColumn(table, SWT.NONE);
+ typeTableColumn.setWidth(120);
+ typeTableColumn.setText(MessagesForTracepointActions.TracepointActions_Type);
+
+ final TableColumn summaryTableColumn = new TableColumn(table, SWT.NONE);
+ summaryTableColumn.setWidth(120);
+ summaryTableColumn.setText(MessagesForTracepointActions.TracepointActions_Summary);
+
+ ArrayList actions = TracepointActionManager.getInstance().getActions();
+ boolean hasActions = actions.size() > 0;
+
+ for (ITracepointAction element : actions) {
+ if (isSubAction && element instanceof WhileSteppingAction) continue;
+ final TableItem tableItem = new TableItem(table, SWT.NONE);
+ tableItem.setText(0, element.getName());
+ tableItem.setText(1, element.getTypeName());
+ tableItem.setText(2, element.getSummary());
+ tableItem.setData(element);
+ }
+
+ if (useAttachButton) {
+ attachButton = new Button(this, SWT.NONE);
+ attachButton.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+ attachButton.setText(MessagesForTracepointActions.TracepointActions_Attach);
+ }
+
+ newButton = new Button(this, SWT.NONE);
+ newButton.setLayoutData(new GridData());
+ newButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ try {
+ HandleNewButton();
+ } catch (CoreException e1) {
+ }
+ }
+ });
+ newButton.setText(MessagesForTracepointActions.TracepointActions_New);
+ newButton.setEnabled(true);
+
+ editButton = new Button(this, SWT.NONE);
+ editButton.setText(MessagesForTracepointActions.TracepointActions_Edit);
+ editButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ HandleEditButton();
+ }
+ });
+ if (!useAttachButton)
+ editButton.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL + GridData.HORIZONTAL_ALIGN_END));
+ editButton.setEnabled(hasActions);
+
+ deleteButton = new Button(this, SWT.NONE);
+ deleteButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+ deleteButton.setText(MessagesForTracepointActions.TracepointActions_Delete);
+ deleteButton.setEnabled(hasActions);
+ }
+
+ public Button getAttachButton() {
+ return attachButton;
+ }
+
+ public Button getDeleteButton() {
+ return deleteButton;
+ }
+
+ public ITracepointAction[] getSelectedActions() {
+ TableItem[] selectedItems = table.getSelection();
+ ITracepointAction[] actionList = new ITracepointAction[selectedItems.length];
+ int actionCount = 0;
+ for (int i = 0; i < selectedItems.length; i++) {
+ actionList[actionCount++] = (ITracepointAction) selectedItems[i].getData();
+ }
+ return actionList;
+ }
+
+ protected void HandleDeleteButton() {
+ TableItem[] selectedItems = table.getSelection();
+ for (int i = 0; i < selectedItems.length; i++) {
+ ITracepointAction action = (ITracepointAction) selectedItems[i].getData();
+ TracepointActionManager.getInstance().deleteAction(action);
+ }
+ table.remove(table.getSelectionIndices());
+ if (table.getItemCount() > 0) {
+ table.select(table.getItemCount() - 1);
+ }
+ updateButtons();
+ }
+
+ protected void HandleEditButton() {
+
+ TableItem[] selectedItems = table.getSelection();
+ ITracepointAction action = (ITracepointAction) selectedItems[0].getData();
+
+ TracepointActionDialog dialog = new TracepointActionDialog(this.getShell(), action, isSubAction);
+ int result = dialog.open();
+ if (result == Window.OK) {
+ action.setName(dialog.getActionName());
+ selectedItems[0].setText(0, action.getName());
+ selectedItems[0].setText(1, action.getTypeName());
+ selectedItems[0].setText(2, action.getSummary());
+ }
+
+ }
+
+ protected void HandleNewButton() throws CoreException {
+
+ TracepointActionDialog dialog = new TracepointActionDialog(this.getShell(), null, isSubAction);
+ int result = dialog.open();
+ if (result == Window.OK) {
+ ITracepointAction action = (ITracepointAction)dialog.getTracepointAction();
+ action.setName(dialog.getActionName());
+ TracepointActionManager.getInstance().addAction(action);
+ final TableItem tableItem = new TableItem(table, SWT.NONE);
+ tableItem.setText(0, action.getName());
+ tableItem.setText(1, action.getTypeName());
+ tableItem.setText(2, action.getSummary());
+ tableItem.setData(action);
+
+ }
+
+ }
+
+ public void updateButtons() {
+ TableItem[] selectedItems = table.getSelection();
+ if (attachButton != null)
+ attachButton.setEnabled(selectedItems.length > 0);
+ deleteButton.setEnabled(selectedItems.length > 0);
+ editButton.setEnabled(selectedItems.length == 1);
+ }
+
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/WhileSteppingActionPage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/WhileSteppingActionPage.java
new file mode 100644
index 00000000000..abc47339bac
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/WhileSteppingActionPage.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.ui.tracepointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.cdt.debug.ui.breakpointactions.IBreakpointActionPage;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.WhileSteppingAction;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.swt.SWT;
+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.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @since 2.1
+ */
+public class WhileSteppingActionPage extends PlatformObject implements IBreakpointActionPage {
+
+ private WhileSteppingAction fWhileSteppingAction;
+ private Text fStepCountText;
+ private TracepointActionsList actionsList;
+ private TracepointGlobalActionsList globalActionsList;
+
+ /**
+ * Create the composite
+ */
+ private Composite createWhileSteppingActionComposite(Composite parent, int style) {
+
+ Composite composite = new Composite(parent, SWT.NULL);
+ composite.setLayout(new GridLayout(2, false));
+
+ final Label stepCountLabel = new Label(composite, SWT.NONE);
+ stepCountLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+ stepCountLabel.setText(MessagesForTracepointActions.TracepointActions_Step_Count);
+
+ fStepCountText = new Text(composite, SWT.BORDER);
+ fStepCountText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ fStepCountText.setText(Integer.toString(fWhileSteppingAction.getStepCount()));
+
+ final Label actionsTriggeredWhenLabel = new Label(composite, SWT.NONE);
+ actionsTriggeredWhenLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+ actionsTriggeredWhenLabel.setText(MessagesForTracepointActions.TracepointActions_WhileStepping_Sub_Actions);
+
+ actionsList = new TracepointActionsList(composite, SWT.NONE);
+ GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+ gridData.horizontalSpan = 2;
+ actionsList.setLayoutData(gridData);
+
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ composite.setLayout(gridLayout);
+
+ final Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
+ gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ gridData.horizontalSpan = 2;
+ label.setLayoutData(gridData);
+
+ final Label allAvailableActionsLabel = new Label(composite, SWT.NONE);
+ gridData = new GridData();
+ gridData.horizontalSpan = 2;
+ allAvailableActionsLabel.setLayoutData(gridData);
+ allAvailableActionsLabel.setText(MessagesForTracepointActions.TracepointActions_Available_actions);
+
+ globalActionsList = new TracepointGlobalActionsList(composite, SWT.NONE, true, true);
+ gridData = new GridData(GridData.FILL_BOTH);
+ gridData.horizontalSpan = 2;
+ globalActionsList.setLayoutData(gridData);
+
+ String actionNames = fWhileSteppingAction.getSubActionsNames();
+ actionsList.setNames(actionNames);
+
+ globalActionsList.getAttachButton().addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ HandleAttachButton();
+ }
+ });
+
+ globalActionsList.getDeleteButton().addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ HandleDeleteButton();
+ }
+ });
+
+ return composite;
+ }
+
+ protected void HandleAttachButton() {
+ ITracepointAction[] selectedActions = globalActionsList.getSelectedActions();
+ for (ITracepointAction action : selectedActions) {
+ actionsList.addAction(action);
+ }
+ }
+
+ /**
+ * Clean up attached actions that were just deleted from the GlobalActionList
+ *
+ * @since 7.0
+ */
+ protected void HandleDeleteButton() {
+ // First remove any attached action that was just deleted
+ ITracepointAction[] selectedActions = globalActionsList.getSelectedActions();
+ for (ITracepointAction action : selectedActions) {
+ actionsList.removeAction(action);
+ }
+ // Now cleanup the global action list
+ globalActionsList.HandleDeleteButton();
+ }
+
+ public WhileSteppingAction getWhileSteppingAction() {
+ return fWhileSteppingAction;
+ }
+
+ public void actionDialogCanceled() {
+ }
+
+ public void actionDialogOK() {
+ // Make sure we are dealing with an int
+ int count = 1;
+ try {
+ count = Integer.parseInt(fStepCountText.getText());
+ } catch (NumberFormatException e) {
+ }
+ fWhileSteppingAction.setStepCount(count);
+
+ fWhileSteppingAction.setSubActionsNames(actionsList.getActionNames());
+ fWhileSteppingAction.setSubActionsContent(actionsList.getActionNames());
+ }
+
+ public Composite createComposite(IBreakpointAction action, Composite composite, int style) {
+ fWhileSteppingAction = (WhileSteppingAction)action;
+ return createWhileSteppingActionComposite(composite, style);
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/messages.properties
new file mode 100644
index 00000000000..f4e71343260
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/messages.properties
@@ -0,0 +1,31 @@
+###############################################################################
+# Copyright (c) 2010 Ericsson 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:
+# Ericsson - initial API and implementation
+###############################################################################
+
+TracepointActions_Actions_for_this_tracepoint=Actions for this tracepoint:
+TracepointActions_Available_actions=Available actions:
+TracepointActions_Name=Name
+TracepointActions_Type=Type
+TracepointActions_Summary=Summary
+TracepointActions_Attach=Attach
+TracepointActions_New=New...
+TracepointActions_Edit=Edit...
+TracepointActions_Delete=Delete
+TracepointActions_Remove=Remove
+TracepointActions_Up=Up
+TracepointActions_Down=Down
+TracepointActions_Preferences_Actions_Available=Actions available for any tracepoint in the workspace:
+TracepointActions_Step_Count=Step count:
+TracepointActions_ActionDialog_New=New Tracepoint Action
+TracepointActions_ActionDialog_Name=Action name:
+TracepointActions_ActionDialog_Type=Action type:
+TracepointActions_Collect_Label=Data to collect (comma-separated list):
+TracepointActions_Evaluate_Label=Expressions to evaluate (comma-separated list):
+TracepointActions_WhileStepping_Sub_Actions=Sub-actions for While-stepping
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF
index ecf1cba6f41..b50dddae081 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF
@@ -22,6 +22,7 @@ Export-Package: org.eclipse.cdt.dsf.gdb,
org.eclipse.cdt.dsf.gdb.launching,
org.eclipse.cdt.dsf.gdb.service,
org.eclipse.cdt.dsf.gdb.service.command,
+ org.eclipse.cdt.dsf.gdb.internal.tracepointactions,
org.eclipse.cdt.dsf.mi.service,
org.eclipse.cdt.dsf.mi.service.command,
org.eclipse.cdt.dsf.mi.service.command.commands,
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/AbstractTracepointAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/AbstractTracepointAction.java
new file mode 100644
index 00000000000..9f6f25e13be
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/AbstractTracepointAction.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.AbstractBreakpointAction;
+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+/**
+ * @since 3.0
+ */
+public abstract class AbstractTracepointAction extends AbstractBreakpointAction implements ITracepointAction {
+ /**
+ * Tracepoint commands, by default, are not executed in Eclipse, but are executed by the backend.
+ */
+ public IStatus execute(IBreakpoint breakpoint, IAdaptable context, IProgressMonitor monitor) {
+ return new Status(IStatus.OK, GdbPlugin.PLUGIN_ID, null);
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/CollectAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/CollectAction.java
new file mode 100644
index 00000000000..ee082704b51
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/CollectAction.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * @since 3.0
+ */
+public class CollectAction extends AbstractTracepointAction {
+
+ private static final String COLLECT_ACTION_ID = "org.eclipse.cdt.dsf.gdb.tracepointactions.CollectAction"; //$NON-NLS-1$
+
+ private String fCollectString = ""; //$NON-NLS-1$
+
+ public String getDefaultName() {
+ return MessagesForTracepointActions.TracepointActions_Untitled_Collect;
+ }
+
+ public String getCollectString() {
+ return fCollectString;
+ }
+
+ public void setCollectString(String str) {
+ fCollectString = str;
+ }
+
+ public String getIdentifier() {
+ return COLLECT_ACTION_ID;
+ }
+
+ public String getMemento() {
+ String collectData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("collectData"); //$NON-NLS-1$
+ rootElement.setAttribute("collectString", fCollectString); //$NON-NLS-1$
+
+ doc.appendChild(rootElement);
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+
+ DOMSource source = new DOMSource(doc);
+ StreamResult outputTarget = new StreamResult(s);
+ transformer.transform(source, outputTarget);
+
+ collectData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return collectData;
+ }
+
+ public String getSummary() {
+ return MessageFormat.format(MessagesForTracepointActions.TracepointActions_Collect_text, new Object[] { fCollectString });
+ }
+
+ public String getTypeName() {
+ return MessagesForTracepointActions.TracepointActions_Collect_Name;
+ }
+
+ public void initializeFromMemento(String data) {
+ Element root = null;
+ DocumentBuilder parser;
+ try {
+ parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ parser.setErrorHandler(new DefaultHandler());
+ root = parser.parse(new InputSource(new StringReader(data))).getDocumentElement();
+ fCollectString = root.getAttribute("collectString"); //$NON-NLS-1$
+ if (fCollectString == null)
+ throw new Exception();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MessageFormat.format(MessagesForTracepointActions.TracepointActions_Collect_text, new Object[] { fCollectString });
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/EvaluateAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/EvaluateAction.java
new file mode 100644
index 00000000000..0d51805c130
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/EvaluateAction.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * @since 3.0
+ */
+public class EvaluateAction extends AbstractTracepointAction {
+ private static final String EVALUATE_ACTION_ID = "org.eclipse.cdt.dsf.gdb.tracepointactions.EvaluateAction"; //$NON-NLS-1$
+
+ private String fEvalString = ""; //$NON-NLS-1$
+
+ public String getDefaultName() {
+ return MessagesForTracepointActions.TracepointActions_Untitled_Evaluate;
+ }
+
+ public String getEvalString() {
+ return fEvalString;
+ }
+
+ public void setEvalString(String str) {
+ fEvalString = str;
+ }
+
+ public String getIdentifier() {
+ return EVALUATE_ACTION_ID;
+ }
+
+ public String getMemento() {
+ String collectData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("evalData"); //$NON-NLS-1$
+ rootElement.setAttribute("evalString", fEvalString); //$NON-NLS-1$
+
+ doc.appendChild(rootElement);
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+
+ DOMSource source = new DOMSource(doc);
+ StreamResult outputTarget = new StreamResult(s);
+ transformer.transform(source, outputTarget);
+
+ collectData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return collectData;
+ }
+
+ public String getSummary() {
+ return MessageFormat.format(MessagesForTracepointActions.TracepointActions_Evaluate_text, new Object[] { fEvalString });
+ }
+
+ public String getTypeName() {
+ return MessagesForTracepointActions.TracepointActions_Evaluate_Name;
+ }
+
+ public void initializeFromMemento(String data) {
+ Element root = null;
+ DocumentBuilder parser;
+ try {
+ parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ parser.setErrorHandler(new DefaultHandler());
+ root = parser.parse(new InputSource(new StringReader(data))).getDocumentElement();
+ fEvalString = root.getAttribute("evalString"); //$NON-NLS-1$
+ if (fEvalString == null)
+ throw new Exception();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MessageFormat.format(MessagesForTracepointActions.TracepointActions_Evaluate_text, new Object[] { fEvalString });
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/ITracepointAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/ITracepointAction.java
new file mode 100644
index 00000000000..89f71b99f37
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/ITracepointAction.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Erucsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+
+
+/**
+ * Marker interface to differentiate between different breakpoint actions
+ * @since 3.0
+ */
+public interface ITracepointAction extends IBreakpointAction {
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/MessagesForTracepointActions.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/MessagesForTracepointActions.java
new file mode 100644
index 00000000000..72ace6d2136
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/MessagesForTracepointActions.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Preference strings.
+ * @since 3.0
+ */
+class MessagesForTracepointActions extends NLS {
+ private static final String BUNDLE_NAME= "org.eclipse.cdt.dsf.gdb.internal.tracepointactions.messages"; //$NON-NLS-1$
+
+ public static String TracepointActions_Untitled_Collect;
+ public static String TracepointActions_Untitled_Evaluate;
+ public static String TracepointActions_Untitled_WhileStepping;
+ public static String TracepointActions_Collect_Name;
+ public static String TracepointActions_Evaluate_Name;
+ public static String TracepointActions_WhileStepping_Name;
+ public static String TracepointActions_Collect_text;
+ public static String TracepointActions_Evaluate_text;
+ public static String TracepointActions_WhileStepping_text;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, MessagesForTracepointActions.class);
+ }
+
+ private MessagesForTracepointActions() {
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/TracepointActionManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/TracepointActionManager.java
new file mode 100644
index 00000000000..cb415e7a069
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/TracepointActionManager.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * @since 3.0
+ */
+public class TracepointActionManager {
+
+ private static final String TRACEPOINT_ACTION_DATA = "TracepointActionManager.actionData"; //$NON-NLS-1$
+ private static final TracepointActionManager fTracepointActionManager = new TracepointActionManager();
+
+ private ArrayList tracepointActions = null;
+
+ private TracepointActionManager() {
+ }
+
+ public static TracepointActionManager getInstance() {
+ return fTracepointActionManager;
+ }
+
+ public void addAction(ITracepointAction action) {
+ getActions().add(action);
+ }
+
+ public void deleteAction(ITracepointAction action) {
+ getActions().remove(action);
+ }
+
+ public ITracepointAction findAction(String name) {
+ for (ITracepointAction action : getActions()) {
+ if (action.getName().equals(name)) {
+ return action;
+ }
+ }
+ return null;
+ }
+
+ public ArrayList getActions() {
+ if (tracepointActions == null) {
+ tracepointActions = new ArrayList();
+ loadActionData();
+ }
+ return tracepointActions;
+ }
+
+ private void loadActionData() {
+
+ String actionData = GdbPlugin.getDefault().getPluginPreferences().getString(TRACEPOINT_ACTION_DATA);
+
+ if (actionData == null || actionData.length() == 0)
+ return;
+
+ Element root = null;
+ DocumentBuilder parser;
+ try {
+ parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ parser.setErrorHandler(new DefaultHandler());
+ root = parser.parse(new InputSource(new StringReader(actionData))).getDocumentElement();
+
+ NodeList nodeList = root.getChildNodes();
+ int entryCount = nodeList.getLength();
+
+ for (int i = 0; i < entryCount; i++) {
+ Node node = nodeList.item(i);
+ short type = node.getNodeType();
+ if (type == Node.ELEMENT_NODE) {
+ Element subElement = (Element) node;
+ String nodeName = subElement.getNodeName();
+ if (nodeName.equalsIgnoreCase("actionEntry")) { //$NON-NLS-1$
+ String name = subElement.getAttribute("name"); //$NON-NLS-1$
+ if (name == null)
+ throw new Exception();
+ String value = subElement.getAttribute("value"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ String className = subElement.getAttribute("class"); //$NON-NLS-1$
+ if (className == null)
+ throw new Exception();
+
+ ITracepointAction action = (ITracepointAction)Class.forName(className).newInstance();
+ action.setName(name);
+ action.initializeFromMemento(value);
+ addAction(action);
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String makeUniqueActionName(String defaultName) {
+ String result = defaultName;
+ ITracepointAction action = findAction(defaultName);
+ int actionCount = 1;
+ while (action != null) {
+ result = defaultName + "(" + actionCount + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ action = findAction(result);
+ actionCount++;
+ }
+ return result;
+ }
+
+ public void revertActionData() {
+ tracepointActions = null;
+ }
+
+ public void saveActionData() {
+ String actionData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("tracepointActionData"); //$NON-NLS-1$
+ doc.appendChild(rootElement);
+
+ for (Iterator iter = getActions().iterator(); iter.hasNext();) {
+ ITracepointAction action = iter.next();
+
+ Element element = doc.createElement("actionEntry"); //$NON-NLS-1$
+ element.setAttribute("name", action.getName()); //$NON-NLS-1$
+ element.setAttribute("class", action.getClass().getName()); //$NON-NLS-1$
+ element.setAttribute("value", action.getMemento()); //$NON-NLS-1$
+ rootElement.appendChild(element);
+
+ }
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+
+ DOMSource source = new DOMSource(doc);
+ StreamResult outputTarget = new StreamResult(s);
+ transformer.transform(source, outputTarget);
+
+ actionData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ GdbPlugin.getDefault().getPluginPreferences().setValue(TRACEPOINT_ACTION_DATA, actionData);
+ GdbPlugin.getDefault().savePluginPreferences();
+ }
+
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/WhileSteppingAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/WhileSteppingAction.java
new file mode 100644
index 00000000000..bfbb96713b2
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/WhileSteppingAction.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal.tracepointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * @since 3.0
+ */
+public class WhileSteppingAction extends AbstractTracepointAction {
+ private static final String WHILE_STEPPING_ACTION_ID = "org.eclipse.cdt.dsf.gdb.tracepointactions.WhileSteppingAction"; //$NON-NLS-1$
+
+ // The name of the sub actions
+ private String fSubActionNames = ""; //$NON-NLS-1$
+ // A comma-separated string of the actual content of each sub command
+ // This is the string than can be sent to GDB
+ private String fSubActionContent = ""; //$NON-NLS-1$
+ // The number of steps this while-stepping command will occur
+ private int fStepCount = 1;
+
+ public String getDefaultName() {
+ return MessagesForTracepointActions.TracepointActions_Untitled_WhileStepping;
+ }
+
+ public String getSubActionsNames() {
+ return fSubActionNames;
+ }
+
+ public void setSubActionsNames(String str) {
+ fSubActionNames = str;
+ }
+
+ public String getSubActionsContent() {
+ return fSubActionContent;
+ }
+
+ // Take all the sub action names, and find their corresponding action,
+ // then build the content string
+ public void setSubActionsContent(String subActionNames) {
+ String[] names = subActionNames.split(","); //$NON-NLS-1$
+ fSubActionContent = ""; //$NON-NLS-1$
+
+ for (String name : names) {
+ ITracepointAction action = TracepointActionManager.getInstance().findAction(name.trim());
+ if (action != null) {
+ fSubActionContent += action.getSummary() + ","; //$NON-NLS-1$
+ }
+ }
+ // Remove last comma
+ if (fSubActionContent.length() >0) {
+ fSubActionContent = fSubActionContent.substring(0, fSubActionContent.length()-1);
+ }
+ }
+
+ public int getStepCount() {
+ return fStepCount;
+ }
+
+ public void setStepCount(int count) {
+ fStepCount = count;
+ }
+
+ public String getIdentifier() {
+ return WHILE_STEPPING_ACTION_ID;
+ }
+
+ public String getMemento() {
+ String collectData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("whileSteppingData"); //$NON-NLS-1$
+ rootElement.setAttribute("whileSteppingCount", Integer.toString(fStepCount)); //$NON-NLS-1$
+ rootElement.setAttribute("subActionNames", fSubActionNames); //$NON-NLS-1$
+
+ doc.appendChild(rootElement);
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+
+ DOMSource source = new DOMSource(doc);
+ StreamResult outputTarget = new StreamResult(s);
+ transformer.transform(source, outputTarget);
+
+ collectData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return collectData;
+ }
+
+ public String getSummary() {
+ return MessageFormat.format(MessagesForTracepointActions.TracepointActions_WhileStepping_text, new Object[] { fStepCount, fSubActionContent });
+ }
+
+ public String getTypeName() {
+ return MessagesForTracepointActions.TracepointActions_WhileStepping_Name;
+ }
+
+ public void initializeFromMemento(String data) {
+ Element root = null;
+ DocumentBuilder parser;
+ try {
+ parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ parser.setErrorHandler(new DefaultHandler());
+ root = parser.parse(new InputSource(new StringReader(data))).getDocumentElement();
+ setStepCount(Integer.parseInt(root.getAttribute("whileSteppingCount"))); //$NON-NLS-1$
+ setSubActionsNames(root.getAttribute("subActionNames")); //$NON-NLS-1$
+ if (fSubActionNames == null)
+ throw new Exception();
+ setSubActionsContent(fSubActionNames);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MessageFormat.format(MessagesForTracepointActions.TracepointActions_WhileStepping_text, new Object[] { fStepCount, fSubActionContent });
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/messages.properties
new file mode 100644
index 00000000000..5663bd75c2f
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/messages.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2010 Ericsson 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:
+# Ericsson - initial API and implementation
+###############################################################################
+
+TracepointActions_Untitled_Collect=Untitled Collect Action
+TracepointActions_Untitled_Evaluate=Untitled Evaluate Action
+TracepointActions_Untitled_WhileStepping=Untitled While-Stepping Action
+TracepointActions_Collect_Name=Collect Action
+TracepointActions_Evaluate_Name=Evaluate Action
+TracepointActions_WhileStepping_Name=While-Stepping Action
+TracepointActions_Collect_text=collect {0}
+TracepointActions_Evaluate_text=eval {0}
+TracepointActions_WhileStepping_text=while-stepping {0} {1}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java
index 6c715220092..03358d7029f 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
@@ -24,6 +25,8 @@ import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
+import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.TracepointActionManager;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData;
@@ -243,9 +246,11 @@ public class GDBBreakpoints_7_0 extends MIBreakpoints
// If it wasn't supposed to be, then disable it right away
// Also, tracepoints are created with no passcount.
// We have to set the passcount manually now.
+ // Same for commands.
Map delta = new HashMap();
delta.put(MIBreakpoints.IS_ENABLED, getProperty(attributes, MIBreakpoints.IS_ENABLED, true));
delta.put(MIBreakpoints.PASS_COUNT, getProperty(attributes, MIBreakpoints.PASS_COUNT, 0));
+ delta.put(MIBreakpoints.COMMANDS, getProperty(attributes, MIBreakpoints.COMMANDS, "")); //$NON-NLS-1$
modifyBreakpoint(dmc, delta, drm, false);
return;
}
@@ -297,74 +302,72 @@ public class GDBBreakpoints_7_0 extends MIBreakpoints
attributes.remove(passCountAttribute);
}
-// // Determine if the breakpoint state changed
-// String commandsAttribute = MIBreakpoints.COMMANDS;
-// if (properties.containsKey(commandsAttribute)) {
-// String oldValue = "khouzam"; //TODO
-// String newValue = (String) properties.get(commandsAttribute);
-// if (newValue == null) newValue = NULL_STRING;
-// if (!oldValue.equals(newValue)) {
-// IBreakpointAction[] actions = generateGdbActions(newValue);
-// numberOfChanges++;
-// changeActions(context, reference, actions, countingRm);
-// }
-// properties.remove(commandsAttribute);
-// }
+ // Determine if tracepoint commands changed
+ // Note that breakpoint commands (actions) are not handled by the backend
+ // which is why we don't check for changes here
+ String commandsAttribute = MIBreakpoints.COMMANDS;
+ if (attributes.containsKey(commandsAttribute) &&
+ breakpoint.getBreakpointType().equals(MIBreakpoints.TRACEPOINT)) {
+ String oldValue = breakpoint.getCommands();
+ String newValue = (String) attributes.get(commandsAttribute);
+ if (newValue == null) newValue = NULL_STRING;
+ if (!oldValue.equals(newValue)) {
+ ITracepointAction[] actions = generateGdbCommands(newValue);
+ numberOfChanges++;
+ changeActions(context, reference, newValue, actions, countingRm);
+ }
+ attributes.remove(commandsAttribute);
+ }
// Set the number of completions required
countingRm.setDoneCount(numberOfChanges);
}
+
+ private ITracepointAction[] generateGdbCommands(String actionStr) {
+ String[] actionNames = actionStr.split(","); //$NON-NLS-1$
+ ITracepointAction[] actions = new ITracepointAction[actionNames.length];
-// private IBreakpointAction[] generateGdbActions(String actionStr) {
-// String[] actionNames = actionStr.split(",");
-// IBreakpointAction[] actions = new IBreakpointAction[actionNames.length];
-//
-// for (int i = 0; i < actionNames.length; i++) {
-// BreakpointActionManager actionManager = CDebugCorePlugin.getDefault().getBreakpointActionManager();
-// actions[i] = actionManager.findTracepointAction(actionNames[i]);
-// }
-// return actions;
-// }
+ TracepointActionManager actionManager = TracepointActionManager.getInstance();
+ for (int i = 0; i < actionNames.length; i++) {
+ actions[i] = actionManager.findAction(actionNames[i]);
+ }
+ return actions;
+ }
-// private void changeActions(final IBreakpointsTargetDMContext context,
-// final int reference, final IBreakpointAction[] actions, final RequestMonitor rm)
-// {
-// // Pick the context breakpoints map
-// final Map contextBreakpoints = fBreakpoints.get(context);
-// if (contextBreakpoints == null) {
-// rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null));
-// rm.done();
-// return;
-// }
-//
-// // We only do this for tracepoints
-//
-// ArrayList actionStrings = new ArrayList();
-// for (int i = 0; i< actions.length; i++) {
-// IBreakpointAction action = actions[i];
-// if (action != null) {
-// actionStrings.add(action.toString());
-// }
-// }
-// // Queue the command
-// //TODO should we use a cache?
-// fConnection.queueCommand(
-// new MIBreakCommands(context, reference, actionStrings.toArray(new String[0])),
-// new DataRequestMonitor(getExecutor(), rm) {
-// @Override
-// protected void handleSuccess() {
-//// MIBreakpointDMData breakpoint = contextBreakpoints.get(reference);
-//// if (breakpoint == null) {
-//// rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null));
-//// rm.done();
-//// return;
-//// }
-//// breakpoint.setCondition(condition);
-// rm.done();
-// }
-// });
-// }
+ private void changeActions(final IBreakpointsTargetDMContext context,
+ final int reference, final String actionNames, final ITracepointAction[] actions, final RequestMonitor rm)
+ {
+ // Pick the context breakpoints map
+ final Map contextBreakpoints = getBreakpointMap(context);
+ if (contextBreakpoints == null) {
+ rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null));
+ rm.done();
+ return;
+ }
+
+ ArrayList actionStrings = new ArrayList();
+ for (ITracepointAction action : actions) {
+ if (action != null) {
+ actionStrings.add(action.getSummary());
+ }
+ }
+ fConnection.queueCommand(
+ fCommandFactory.createMIBreakCommands(context, reference, actionStrings.toArray(new String[0])),
+ new DataRequestMonitor(getExecutor(), rm) {
+ @Override
+ protected void handleSuccess() {
+ MIBreakpointDMData breakpoint = contextBreakpoints.get(reference);
+ if (breakpoint == null) {
+ rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT, null));
+ rm.done();
+ return;
+ }
+ breakpoint.setCommands(actionNames);
+ rm.done();
+ }
+ });
+ }
/**
* Update the breakpoint ignoreCount.
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java
index 1010d226f3c..58714b0ad56 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Ericsson and others.
+ * Copyright (c) 2007, 2010 Ericsson 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
@@ -91,6 +91,7 @@ public class MIBreakpointDMData implements IBreakpointDMData {
fProperties.put(MIBreakpoints.CONDITION, dsfMIBreakpoint.getCondition());
fProperties.put(MIBreakpoints.IGNORE_COUNT, dsfMIBreakpoint.getIgnoreCount());
fProperties.put(MIBreakpoints.IS_ENABLED, new Boolean(dsfMIBreakpoint.isEnabled()));
+ fProperties.put(MIBreakpoints.COMMANDS, dsfMIBreakpoint.getCommands());
// MI-specific breakpoint attributes
fProperties.put(NUMBER, dsfMIBreakpoint.getNumber());
@@ -126,8 +127,9 @@ public class MIBreakpointDMData implements IBreakpointDMData {
fProperties.put(MIBreakpoints.FUNCTION, dsfMIBreakpoint.getFunction());
fProperties.put(MIBreakpoints.ADDRESS, dsfMIBreakpoint.getAddress());
fProperties.put(MIBreakpoints.CONDITION, dsfMIBreakpoint.getCondition());
- fProperties.put(MIBreakpoints.IGNORE_COUNT, dsfMIBreakpoint.getPassCount());
+ fProperties.put(MIBreakpoints.PASS_COUNT, dsfMIBreakpoint.getPassCount());
fProperties.put(MIBreakpoints.IS_ENABLED, new Boolean(dsfMIBreakpoint.isEnabled()));
+ fProperties.put(MIBreakpoints.COMMANDS, dsfMIBreakpoint.getCommands());
// MI-specific breakpoint attributes
fProperties.put(NUMBER, dsfMIBreakpoint.getNumber());
@@ -302,9 +304,17 @@ public class MIBreakpointDMData implements IBreakpointDMData {
*/
public void setPassCount(int count) {
fBreakpoint.setPassCount(count);
- fProperties.put(MIBreakpoints.IGNORE_COUNT, count);
+ fProperties.put(MIBreakpoints.PASS_COUNT, count);
}
+ /**
+ * @since 3.0
+ */
+ public void setCommands(String commands) {
+ fBreakpoint.setCommands(commands);
+ fProperties.put(MIBreakpoints.COMMANDS, commands);
+ }
+
public boolean isReadWatchpoint() {
return fBreakpoint.isReadWatchpoint();
}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java
index ede3733a828..4fca97126e0 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java
@@ -1659,6 +1659,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
properties.put(MIBreakpoints.LINE_NUMBER, attributes.get(IMarker.LINE_NUMBER));
properties.put(MIBreakpoints.FUNCTION, attributes.get(ICLineBreakpoint.FUNCTION));
properties.put(MIBreakpoints.ADDRESS, attributes.get(ICLineBreakpoint.ADDRESS));
+ properties.put(MIBreakpoints.COMMANDS, attributes.get(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE));
if (breakpoint instanceof ICTracepoint) {
// A tracepoint is a LineBreakpoint, but needs its own type
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java
index 54dca7c6294..60b4e7a68a7 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java
@@ -39,6 +39,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetEnv;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter;
+import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCommands;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCondition;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDelete;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDisable;
@@ -239,6 +240,10 @@ public class CommandFactory {
return new MIBreakCondition(ctx, breakpoint, condition);
}
+ public ICommand createMIBreakCommands(IBreakpointsTargetDMContext ctx, int breakpoint, String[] commands) {
+ return new MIBreakCommands(ctx, breakpoint, commands);
+ }
+
public ICommand createMIBreakDelete(IBreakpointsTargetDMContext ctx, int[] array) {
return new MIBreakDelete(ctx, array);
}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIBreakCommands.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIBreakCommands.java
new file mode 100644
index 00000000000..f036be3d138
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIBreakCommands.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson 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:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.dsf.mi.service.command.commands;
+
+import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
+import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
+
+/**
+ *
+ * -break-commands NUMBER [ COMMAND-1 ... COMMAND-N ]
+ *
+ * Specifies the CLI commands that should be executed when breakpoint NUMBER is hit.
+ * The parameters COMMAND-1 to COMMAND-N are the commands. If no command is specified,
+ * any previously-set commands are cleared.
+ *
+ * Available since GDB 7.0
+ *
+ * @since 3.0
+ */
+
+public class MIBreakCommands extends MICommand
+{
+ public MIBreakCommands(IBreakpointsTargetDMContext ctx, int breakpoint, String[] commands) {
+ super(ctx, "-break-commands"); //$NON-NLS-1$
+ if (commands == null) {
+ setParameters(new String[] { Integer.toString(breakpoint) });
+ } else {
+ String[] params = new String[commands.length + 1];
+ params[0] = Integer.toString(breakpoint);
+ for (int i = 1; i < params.length; i++) {
+ params[i] = commands[i-1];
+ }
+ setParameters(params);
+ }
+ }
+}