From 438a83dada05ac581688ed2d3bc6667159fcbf23 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 11 Mar 2010 19:09:40 +0000 Subject: [PATCH] [284286] Support for setting tracepoint actions --- .../META-INF/MANIFEST.MF | 1 + .../plugin.properties | 2 + dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml | 44 +++ .../tracepointactions/CollectActionPage.java | 66 +++++ .../tracepointactions/EvaluateActionPage.java | 66 +++++ .../MessagesForTracepointActions.java | 50 ++++ .../TracepointActionDialog.java | 277 ++++++++++++++++++ .../TracepointActionsList.java | 204 +++++++++++++ .../TracepointActionsPreferencePage.java | 70 +++++ .../TracepointActionsPropertyPage.java | 157 ++++++++++ .../TracepointGlobalActionsList.java | 204 +++++++++++++ .../WhileSteppingActionPage.java | 148 ++++++++++ .../ui/tracepointactions/messages.properties | 31 ++ .../META-INF/MANIFEST.MF | 1 + .../AbstractTracepointAction.java | 31 ++ .../tracepointactions/CollectAction.java | 116 ++++++++ .../tracepointactions/EvaluateAction.java | 115 ++++++++ .../tracepointactions/ITracepointAction.java | 21 ++ .../MessagesForTracepointActions.java | 39 +++ .../TracepointActionManager.java | 182 ++++++++++++ .../WhileSteppingAction.java | 154 ++++++++++ .../tracepointactions/messages.properties | 20 ++ .../dsf/gdb/service/GDBBreakpoints_7_0.java | 125 ++++---- .../dsf/mi/service/MIBreakpointDMData.java | 16 +- .../dsf/mi/service/MIBreakpointsManager.java | 1 + .../mi/service/command/CommandFactory.java | 5 + .../command/commands/MIBreakCommands.java | 45 +++ 27 files changed, 2127 insertions(+), 64 deletions(-) create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/CollectActionPage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/EvaluateActionPage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/MessagesForTracepointActions.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionDialog.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsList.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPreferencePage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointActionsPropertyPage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/TracepointGlobalActionsList.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/WhileSteppingActionPage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/tracepointactions/messages.properties create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/AbstractTracepointAction.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/CollectAction.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/EvaluateAction.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/ITracepointAction.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/MessagesForTracepointActions.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/TracepointActionManager.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/WhileSteppingAction.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/tracepointactions/messages.properties create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIBreakCommands.java 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); + } + } +}