From 8c037f0524fac2c69e6be9110f2bdcb21c2c5713 Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Fri, 25 Apr 2008 17:39:32 +0000 Subject: [PATCH] bug 226689 - catchpoint support --- .../cdt/debug/core/tests/AllDebugTests.java | 2 +- .../cdt/debug/core/tests/CatchpointTests.java | 98 +++++ .../resources/debugCxxTest.zip | Bin 0 -> 3550 bytes .../META-INF/MANIFEST.MF | 2 + .../icons/obj16/catchpoint_obj.gif | Bin 0 -> 203 bytes .../icons/obj16/catchpointd_obj.gif | Bin 0 -> 226 bytes .../plugin.properties | 2 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 33 ++ .../schema/BreakpointUIContribution.exsd | 196 ++++++++++ .../ui/actions/ActionMessages.properties | 2 + .../actions/AddCatchpointActionDelegate.java | 80 ++++ .../ui/dialogs/AddCatchpointDialog.java | 343 ++++++++++++++++++ .../internal/ui/dialogs/DialogMessages.java | 33 ++ .../ui/dialogs/DialogMessages.properties | 1 + .../CBreakpointPropertyPage.java | 102 +++++- .../PropertyPageMessages.properties | 5 +- .../CBreakpointUIContributionFactory.java | 182 ++++++++++ .../CCatchpointsLabelProviderFactory.java | 156 ++++++++ .../DefaultCBreakpointUIContribution.java | 150 ++++++++ .../ICBreakpointsUIContribution.java | 81 +++++ .../ui/preferences/LabelFieldEditor.java | 24 ++ 21 files changed, 1478 insertions(+), 14 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/CatchpointTests.java create mode 100644 debug/org.eclipse.cdt.debug.ui.tests/resources/debugCxxTest.zip create mode 100755 debug/org.eclipse.cdt.debug.ui/icons/obj16/catchpoint_obj.gif create mode 100755 debug/org.eclipse.cdt.debug.ui/icons/obj16/catchpointd_obj.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/schema/BreakpointUIContribution.exsd create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddCatchpointActionDelegate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/AddCatchpointDialog.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.properties create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointUIContributionFactory.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CCatchpointsLabelProviderFactory.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/ICBreakpointsUIContribution.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/preferences/LabelFieldEditor.java diff --git a/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/AllDebugTests.java b/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/AllDebugTests.java index 0860fc09dfc..7dcf17cbdc0 100644 --- a/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/AllDebugTests.java +++ b/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/AllDebugTests.java @@ -38,7 +38,7 @@ public class AllDebugTests { suite.addTest(DebugTests.suite()); suite.addTest(BreakpointTests.suite()); suite.addTest(LocationTests.suite()); - // suite.addTest(CatchpointTests.suite()); + suite.addTest(CatchpointTests.suite()); return suite; diff --git a/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/CatchpointTests.java b/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/CatchpointTests.java new file mode 100644 index 00000000000..cbe1a079f8d --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/CatchpointTests.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core.tests; + +import java.io.IOException; + +import junit.framework.Test; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.ICDIFunctionLocation; +import org.eclipse.cdt.debug.core.cdi.ICDILocation; +import org.eclipse.cdt.debug.core.cdi.ICDILocator; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement3; +import org.eclipse.cdt.debug.core.cdi.model.ICDICatchpoint; +import org.eclipse.cdt.debug.mi.core.MIException; +import org.eclipse.cdt.debug.mi.core.cdi.model.Catchpoint; + +public class CatchpointTests extends AbstractDebugTest { + public static Test suite() { + return new DebugTestWrapper(CatchpointTests.class){}; + } + + protected String getProjectName() { + return "catchpoints"; + } + + protected String getProjectZip() { + return "resources/debugCxxTest.zip"; + } + + protected String getProjectBinary() { + return "catchpoints"; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + createDebugSession(); + assertNotNull(currentTarget); + currentTarget.deleteAllBreakpoints(); + pause(); + } + + void setBreakOnMain() throws CDIException { + ICDILocation location = null; + location = currentTarget.createFunctionLocation("", "main"); //$NON-NLS-1$ + currentTarget.setFunctionBreakpoint(ICDIBreakpoint.TEMPORARY, (ICDIFunctionLocation) location, null, false); + + } + + public void testCatch() throws CModelException, IOException, MIException, CDIException { + catchpoints(Catchpoint.CATCH, ""); + } + + public void testThrow() throws CModelException, IOException, MIException, CDIException { + catchpoints(Catchpoint.THROW, ""); + } + + private void catchpoints(String type, String arg) throws CModelException, IOException, MIException, CDIException { + ICDIBreakpoint[] breakpoints; + ICDICatchpoint curbreak; + + setBreakOnMain(); + currentTarget.restart(); + waitSuspend(currentTarget); + ICDILocator locator = currentTarget.getThreads()[0].getStackFrames()[0].getLocator(); + assertEquals("Debug should be stopped in function 'main' but it is stopped in: " + locator.getFunction(), + "main", locator.getFunction()); + + currentTarget.deleteAllBreakpoints(); + pause(); + assertTrue(currentTarget instanceof ICDIBreakpointManagement3); + ((ICDIBreakpointManagement3) currentTarget).setCatchpoint(type, arg, ICDIBreakpoint.REGULAR, null, false, true); + pause(); + breakpoints = currentTarget.getBreakpoints(); + assertNotNull(breakpoints); + assertTrue(breakpoints.length == 1); + if (breakpoints[0] instanceof ICDICatchpoint) { + curbreak = (ICDICatchpoint) breakpoints[0]; + } else + curbreak = null; + assertNotNull(curbreak); + currentTarget.resume(false); + waitSuspend(currentTarget); + // it is stopped we are fine, it did hit breakpoint + } + +} diff --git a/debug/org.eclipse.cdt.debug.ui.tests/resources/debugCxxTest.zip b/debug/org.eclipse.cdt.debug.ui.tests/resources/debugCxxTest.zip new file mode 100644 index 0000000000000000000000000000000000000000..d29256144f7081f2ed29dec99ed83e6a9d7649de GIT binary patch literal 3550 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 TA-^{s%}3kx&&F^uGFSrukil$p literal 0 HcmV?d00001 diff --git a/debug/org.eclipse.cdt.debug.ui/icons/obj16/catchpointd_obj.gif b/debug/org.eclipse.cdt.debug.ui/icons/obj16/catchpointd_obj.gif new file mode 100755 index 0000000000000000000000000000000000000000..4a04deca138d692281e0604575e955d6c0c954d1 GIT binary patch literal 226 zcmZ?wbhEHb6krfwXc1*tym;yC*>m^q-M?$s?(&N2jhnW#b#(Ri^5_+j;2nqyCAL&YnAW^3>o zMWp-saYYXcFO8`u0yHEdR9zGr4ou@ + + + + + + + + + + + + + + + + + diff --git a/debug/org.eclipse.cdt.debug.ui/schema/BreakpointUIContribution.exsd b/debug/org.eclipse.cdt.debug.ui/schema/BreakpointUIContribution.exsd new file mode 100644 index 00000000000..85dd1dc6465 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/schema/BreakpointUIContribution.exsd @@ -0,0 +1,196 @@ + + + + + + + + + This extension point provides a mechanism for contributing UI to view and edit breakpoint attributes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + marker type for which attribute labels are applied + + + + + + + + + + debug model Id for this extension is valid +(debugModelId is a property of cbreakpoint) + + + + + + + + + + + + + + + + + + id of the breakpoint attribute, for example "catchpoint.type" + + + + + + + user visible label for the breakpoint attribute value + + + + + + + + + + field editor that will be shown to for given attribute. +If not specified this attribute will not be visible in Common page. + + + + + + + + + + Type of the attribute: boolean, string, integer + + + + + + + + + + Properties of value for parent attribute. +If Value contains child attributes it means that these property only enabled when value of parent attribute equal to current element value + + + + + + + + + + Value of the attribute for which label is declared + + + + + + + User visible label for the breakpoint attribute value + + + + + + + + + + + + + + + CDT 5.0 + + + + + + + + + <pre> +<extension id="com.xyz.coolMarkerLabels" point="org.eclipse.cdt.debug.ui.breakpointContribution"> + <breakpointLabels markerId="com.xyz.coolMarker"> + <attribute name="owner" label="Resource Owner"> + <value value="harris.bob" label="Bob Harris"/> + <value value="harris.mary" label="Mary Harris"/> + </attribute> + </breakpointLabels> + </extension> + + <extension point="org.eclipse.cdt.debug.ui.breakpointContribution"> + <breakpointLabels markerId="org.eclipse.cdt.debug.core.catchpoint"> + <attribute name="org.eclipse.cdt.debug.core.catchpoint.type" label="Catchpoint Type" type="enum"> + <value value="gdb.catch" label="Exception Caught"> + <attribute name="org.eclipse.cdt.debug.core.catchpoint.argument" label="C/C++ Type" + type="string" fieldEditor="org.eclipse.cdt.debug.ui.breakpoints.CTypeSelectorEditor"> + </attribute> + </value> + <value value="gdb.throw" label="Exception Thrown"/> + <value value="gdb.signal" label="Signal Caught"> + <attribute name="org.eclipse.cdt.debug.core.catchpoint.argument" label="Signal Number" + type="integer" fieldEditor="IntegerFieldEditor"> + </attribute> + </value> + </attribute> + </breakpointLabels> + </extension> + </pre> + + + + + + + diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties index 4e1a3c39159..1f2b9468bd9 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties @@ -121,3 +121,5 @@ ToggleDetailPaneAction.7=Hide the Detail Pane so that only the Main Tree View is AddRegisterGroupActionDelegate.0=Error AddRegisterGroupActionDelegate.1=Error(s) occurred adding register group. EditRegisterGroupActionDelegate.0=Unable to edit register group. +AddCatchpointActionDelegate.0=Error adding Event Breakpoint +AddCatchpointActionDelegate.2=Action is not supported by installed debuggers diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddCatchpointActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddCatchpointActionDelegate.java new file mode 100644 index 00000000000..a13670ac465 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddCatchpointActionDelegate.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.internal.ui.dialogs.AddCatchpointDialog; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.UIMessages; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.actions.ActionDelegate; + +/** + * A delegate for the "Add Event Breakpoint" action. + */ +public class AddCatchpointActionDelegate extends ActionDelegate implements IViewActionDelegate { + + private IViewPart fView; + + /* (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + setView(view); + } + + private void setView(IViewPart view) { + fView = view; + } + + protected IViewPart getView() { + return fView; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + AddCatchpointDialog dlg = new AddCatchpointDialog(CDebugUIPlugin.getActiveWorkbenchShell()); + if (dlg.isActive() == false) { + String message = ActionMessages.getString("AddCatchpointActionDelegate.2"); + MessageDialog.openError( getView().getSite().getShell(), UIMessages.getString( "CDebugUIPlugin.0" ), message); + } else { + if (dlg.open() == Window.OK) { + addCatchpoint(dlg.getEventTypeId(), dlg.getEventArgument()); + } + } + } + + protected void addCatchpoint(String id, String arg) { + if (getResource() == null) + return; + try { + CDIDebugModel.createCatchpoint(id, arg, true); //$NON-NLS-1$ + } catch (CoreException ce) { + CDebugUIPlugin.errorDialog(ActionMessages.getString("AddCatchpointActionDelegate.0"), ce); //$NON-NLS-1$ + } + } + + private IResource getResource() { + return ResourcesPlugin.getWorkspace().getRoot(); + } + +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/AddCatchpointDialog.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/AddCatchpointDialog.java new file mode 100644 index 00000000000..0eaab8a0b14 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/AddCatchpointDialog.java @@ -0,0 +1,343 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - Catchpoints support https://bugs.eclipse.org/bugs/show_bug.cgi?id=226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.dialogs; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.model.ICCatchpoint; +import org.eclipse.cdt.debug.internal.core.breakpoints.CCatchpoint; +import org.eclipse.cdt.debug.internal.ui.propertypages.CBreakpointPreferenceStore; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.breakpoints.CBreakpointUIContributionFactory; +import org.eclipse.cdt.debug.ui.breakpoints.ICBreakpointsUIContribution; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +/** + * The "Add Catchpoint" dialog of the "Add catchpoint" action. + */ +public class AddCatchpointDialog extends Dialog implements ModifyListener, SelectionListener { + + private Combo fEventTypeInput; + private String fEventType; + private String fEventArgument; + private Composite fEventArgumentControl; + private HashMap fIdLabelMap = new LinkedHashMap(); + private FieldEditorPreferencePage page; + private CBreakpointUIContributionFactory factory; + private String debugModelId; + + static class ContributedFields extends FieldEditorPreferencePage { + private String modelId; + private String eventType; + + ContributedFields(String modelId, String eventType) { + this.modelId = modelId; + this.eventType = eventType; + noDefaultAndApplyButton(); + setPreferenceStore(new CBreakpointPreferenceStore() { + @Override + public String getDefaultString(String name) { + return ""; + } + }); + } + + @Override + protected void createFieldEditors() { + Composite parent = getFieldEditorParent(); + try { + Map map = new HashMap(); + map.put(ICCatchpoint.EVENT_TYPE_ID, eventType); + ICBreakpointsUIContribution cons[] = CBreakpointUIContributionFactory.getInstance() + .getBreakpointUIContributions(modelId, CCatchpoint.getMarkerType(), map); + for (ICBreakpointsUIContribution con : cons) { + + if (con.getId().equals(ICCatchpoint.EVENT_TYPE_ID)) continue; + FieldEditor fieldEditor = con.getFieldEditor(con.getId(), con.getLabel(), + parent); + getPreferenceStore().setValue(con.getId(),""); + getPreferenceStore().setValue(con.getId()+".valuelabel", ""); + if (fieldEditor != null) + addField(fieldEditor); + } + } catch (Exception ce) { + CDebugUIPlugin.log(ce); + } + } + + } + + /** + * Constructor + * + * @param parentShell + */ + public AddCatchpointDialog(Shell parentShell) { + super(parentShell); + setShellStyle(getShellStyle() | SWT.RESIZE); + factory = CBreakpointUIContributionFactory.getInstance(); + debugModelId = getDebugModelId(); + // Load events + loadEventTypes(); + } + + protected String getDebugModelId() { + return CDIDebugModel.getPluginIdentifier(); + } + + private void loadEventTypes() { + ICBreakpointsUIContribution[] cons = factory.getBreakpointUIContributions(debugModelId, + CCatchpoint.getMarkerType(), null); + for (int i = 0; i < cons.length; i++) { + ICBreakpointsUIContribution con = cons[i]; + if (con.getId().equals(ICCatchpoint.EVENT_TYPE_ID)) { + String[] possibleValues = con.getPossibleValues(); + for (String value : possibleValues) { + fIdLabelMap.put(value, con.getLabelForValue(value)); + } + } + } + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + // The button bar will work better if we make the parent composite + // a single column grid layout. For the widgets we add, we want a + // a two-column grid, so we just create a sub composite for that. + GridLayout gridLayout = new GridLayout(); + parent.setLayout(gridLayout); + + Composite composite = new Composite(parent, SWT.None); + GridData layoutData = new GridData(GridData.FILL_BOTH); + + layoutData.heightHint=100; + composite.setLayoutData(layoutData); + composite.setLayout(new GridLayout(1, false)); + + // Create the controls + createEventTypeControl(composite); + createEventArgumentControl(composite); + + fEventTypeInput.setFocus(); + if (fEventTypeInput.getItemCount() > 0) + fEventTypeInput.select(0); + updateUI(); + return parent; + } + + protected void createEventTypeControl(Composite parent) { + fEventTypeInput = new Combo(parent, SWT.BORDER | SWT.READ_ONLY); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + fEventTypeInput.setLayoutData(gridData); + for (String id : fIdLabelMap.keySet()) { + addEventType(id, fIdLabelMap.get(id)); + } + fEventTypeInput.addSelectionListener(this); + fEventTypeInput.select(0); + + } + + protected void addEventType(String id, String label) { + int index = fEventTypeInput.getItemCount(); + fEventTypeInput.add(label, index); + fEventTypeInput.setData(getIdDataKey(index), id); + } + + private String getIdDataKey(int index) { + return "index." + index; //$NON-NLS-1$ + } + + protected void createEventArgumentControl(Composite parent) { + fEventArgumentControl = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + //layout.marginHeight = 0; + //layout.marginWidth = 0; + fEventArgumentControl.setLayout(layout); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + fEventArgumentControl.setLayoutData(gridData); + updateEventType(); + if (fEventType != null) { + createArgumentSpecificControl(); + } + } + + private void createArgumentSpecificControl() { + page = new ContributedFields(getDebugModelId(), fEventType); + page.createControl(fEventArgumentControl); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + page.getControl().setLayoutData(gridData); + + } + + private void updateArgumentsControl() { + updateEventType(); + if (fEventTypeInput != null) { + if (page != null) { + Control control = page.getControl(); + control.dispose(); + page.dispose(); + page = null; + } + createArgumentSpecificControl(); + fEventArgumentControl.layout(true); + // resize dialog to fit new fields + getShell().pack(); + } + } + + public boolean isActive(){ + return fIdLabelMap.size()>0; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(DialogMessages.getString("AddCatchpointDialog.2")); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + protected void okPressed() { + if (fEventTypeInput != null) { + updateEventType(); + } + if (page != null) { + page.performOk(); + IPreferenceStore preferenceStore = page.getPreferenceStore(); + if (preferenceStore != null) { + fEventArgument = preferenceStore.getString(ICCatchpoint.EVENT_ARG); + } + else + fEventArgument = null; + } + + super.okPressed(); + } + + private void updateEventType() { + int index = fEventTypeInput.indexOf(fEventTypeInput.getText()); + if (index == -1) { + fEventType = null; + return; + } + Object data = fEventTypeInput.getData(getIdDataKey(index)); + fEventType = (String) data; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + public void modifyText(ModifyEvent e) { + if (e.getSource() == fEventTypeInput) { + updateArgumentsControl(); + } + updateUI(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite) + */ + protected Control createButtonBar(Composite parent) { + return super.createButtonBar(parent); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetDefaultSelected(SelectionEvent e) { + // ignore + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + if (e.getSource() == fEventTypeInput) { + updateArgumentsControl(); + } + updateUI(); + + } + + private void updateUI() { + Button b = getButton(IDialogConstants.OK_ID); + if (b == null) { + return; + } + b.setEnabled(okayEnabled()); + + } + + private boolean okayEnabled() { + // validate fields here + String text = fEventTypeInput.getText(); + int index = fEventTypeInput.indexOf(text); + if (index == -1) { + return false; + } + return true; + } + + protected void createButtonsForButtonBar(Composite parent) { + // override so we can change the initial okay enabled state + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true).setEnabled( + okayEnabled()); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + public String getEventTypeId() { + return fEventType; + } + + public String getEventArgument() { + return fEventArgument; + } + +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.java new file mode 100644 index 00000000000..cef4a3340c3 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.dialogs; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class DialogMessages { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.internal.ui.dialogs.DialogMessages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME ); + + private DialogMessages() { + } + + public static String getString( String key ) { + try { + return RESOURCE_BUNDLE.getString( key ); + } + catch( MissingResourceException e ) { + return '!' + key + '!'; + } + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.properties new file mode 100644 index 00000000000..fd7df6a9a5e --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/dialogs/DialogMessages.properties @@ -0,0 +1 @@ +AddCatchpointDialog.2=Add Event Breakpoint... diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java index e1d7b16b2d0..d2344200955 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java @@ -8,6 +8,7 @@ * Contributors: * QNX Software Systems - Initial API and implementation * Nokia - https://bugs.eclipse.org/bugs/show_bug.cgi?id=145606 + * QNX Software Systems - Catchpoints support https://bugs.eclipse.org/bugs/show_bug.cgi?id=226689 *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.propertypages; @@ -16,9 +17,13 @@ import java.util.Iterator; import java.util.List; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICCatchpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICWatchpoint; import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.breakpoints.CBreakpointUIContributionFactory; +import org.eclipse.cdt.debug.ui.breakpoints.ICBreakpointsUIContribution; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -252,6 +257,8 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement */ protected void createFieldEditors() { ICBreakpoint breakpoint = getBreakpoint(); + createMainLabel(breakpoint); + createContributetedFieldEditors(breakpoint); createTypeSpecificLabelFieldEditors( breakpoint ); createEnabledField( getFieldEditorParent() ); IPreferenceStore store = getPreferenceStore(); @@ -272,15 +279,20 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } } + private void createMainLabel(ICBreakpoint breakpoint) { + addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.18" ), + getBreakpointMainLabel(breakpoint) ) ); //$NON-NLS-1$ + } + /** * Method createTypeSpecificLabelFieldEditors. * * @param breakpoint */ private void createTypeSpecificLabelFieldEditors( ICBreakpoint breakpoint ) { + if ( breakpoint instanceof ICFunctionBreakpoint ) { ICFunctionBreakpoint fbrkpt = (ICFunctionBreakpoint)breakpoint; - addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.18" ), PropertyPageMessages.getString( "CBreakpointPropertyPage.3" ) ) ); //$NON-NLS-1$//$NON-NLS-2$ String function = PropertyPageMessages.getString( "CBreakpointPropertyPage.1" ); //$NON-NLS-1$ try { function = fbrkpt.getFunction(); @@ -295,7 +307,6 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } else if ( breakpoint instanceof ICAddressBreakpoint ) { ICAddressBreakpoint abrkpt = (ICAddressBreakpoint)breakpoint; - addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.18" ), PropertyPageMessages.getString( "CBreakpointPropertyPage.6" ) ) ); //$NON-NLS-1$//$NON-NLS-2$ String address = PropertyPageMessages.getString( "CBreakpointPropertyPage.4" ); //$NON-NLS-1$ try { address = abrkpt.getAddress(); @@ -308,21 +319,13 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } else if ( breakpoint instanceof ICWatchpoint ) { ICWatchpoint watchpoint = (ICWatchpoint)breakpoint; - String type = ""; //$NON-NLS-1$ String expression = ""; //$NON-NLS-1$ try { - if ( watchpoint.isReadType() && !watchpoint.isWriteType() ) - type = PropertyPageMessages.getString( "CBreakpointPropertyPage.11" ); //$NON-NLS-1$ - else if ( !watchpoint.isReadType() && watchpoint.isWriteType() ) - type = PropertyPageMessages.getString( "CBreakpointPropertyPage.12" ); //$NON-NLS-1$ - else - type = PropertyPageMessages.getString( "CBreakpointPropertyPage.13" ); //$NON-NLS-1$ expression = watchpoint.getExpression(); } catch( CoreException ce ) { CDebugUIPlugin.log( ce ); } - addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.18" ), type ) ); //$NON-NLS-1$ IProject project = breakpoint.getMarker().getResource().getProject(); if ( project != null ) { addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.10" ), project.getName() ) ); //$NON-NLS-1$ @@ -337,7 +340,6 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.14" ), expression ) ); //$NON-NLS-1$ } else if ( breakpoint instanceof ILineBreakpoint ) { - addField( createLabelEditor( getFieldEditorParent(), PropertyPageMessages.getString( "CBreakpointPropertyPage.18" ), PropertyPageMessages.getString( "CBreakpointPropertyPage.8" ) ) ); //$NON-NLS-1$//$NON-NLS-2$ String fileName = null; try { fileName = breakpoint.getSourceHandle(); @@ -362,6 +364,41 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } } } + + private String getBreakpointMainLabel(ICBreakpoint breakpoint) { + if (breakpoint instanceof ICFunctionBreakpoint) + return PropertyPageMessages.getString("CBreakpointPropertyPage.3"); + if (breakpoint instanceof ICAddressBreakpoint) + return PropertyPageMessages.getString("CBreakpointPropertyPage.4"); + if (breakpoint instanceof ICLineBreakpoint) + return PropertyPageMessages.getString("CBreakpointPropertyPage.8"); + if (breakpoint instanceof ICCatchpoint) + return PropertyPageMessages.getString("CBreakpointPropertyPage.21"); + if (breakpoint instanceof ICWatchpoint) { + ICWatchpoint watchpoint = (ICWatchpoint) breakpoint; + String type = ""; //$NON-NLS-1$ + try { + if (watchpoint.isReadType() && !watchpoint.isWriteType()) + type = PropertyPageMessages.getString("CBreakpointPropertyPage.11"); //$NON-NLS-1$ + else if (!watchpoint.isReadType() && watchpoint.isWriteType()) + type = PropertyPageMessages.getString("CBreakpointPropertyPage.12"); //$NON-NLS-1$ + else + type = PropertyPageMessages.getString("CBreakpointPropertyPage.13"); //$NON-NLS-1$ + + } catch (CoreException ce) { + CDebugUIPlugin.log(ce); + } + return type; + } + // default main label is the label of marker type for the breakpoint + String type = ""; //$NON-NLS-1$ + try { + type = breakpoint.getMarker().getType(); // TODO: how to get label? + } catch (CoreException ce) { + CDebugUIPlugin.log(ce); + } + return type; + } protected void createLineNumberEditor( Composite parent ) { String title = PropertyPageMessages.getString( "CBreakpointPropertyPage.9" ); BreakpointIntegerFieldEditor labelFieldEditor =new BreakpointIntegerFieldEditor( CBreakpointPreferenceStore.LINE ,title, parent); @@ -458,6 +495,10 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement else if ( property.equals( CBreakpointPreferenceStore.LINE ) ) { // already workspace runnable, setting markers are safe breakpoint.getMarker().setAttribute(IMarker.LINE_NUMBER, getPreferenceStore().getInt(CBreakpointPreferenceStore.LINE)); + } else { + // this allow set attributes contributed by other plugins + String value = getPropertyAsString(property); + breakpoint.getMarker().setAttribute(property, value); } } } @@ -469,4 +510,43 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement CDebugUIPlugin.log( ce ); } } + /** + * Creates field editors contributed using breakpointUIContribution extension point + * @param breakpoint + */ + private void createContributetedFieldEditors(ICBreakpoint breakpoint) { + Composite parent = getFieldEditorParent(); + try { + ICBreakpointsUIContribution cons[] = CBreakpointUIContributionFactory.getInstance() + .getBreakpointUIContributions(breakpoint); + for (ICBreakpointsUIContribution con : cons) { + + FieldEditor fieldEditor = con.getFieldEditor(con.getId(), con.getLabel(), parent); + if (fieldEditor != null) + addField(fieldEditor); + String value = breakpoint.getMarker().getAttribute(con.getId(), ""); + + getPreferenceStore().setValue(con.getId(), value); + // this is used for LabelFieldEditor - not editable value + getPreferenceStore().setValue(con.getId() + ".valuelabel", + con.getLabelForValue(value)); + } + } catch (CoreException ce) { + CDebugUIPlugin.log(ce); + } + + } + + /** + * Return string value of given property or null. + */ + protected String getPropertyAsString(String property) { + // currently only supports String and Integer + IPreferenceStore store = getPreferenceStore(); + + if (store.contains(property)) { + String value = store.getString(property); + return value; + } else return null; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/PropertyPageMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/PropertyPageMessages.properties index 5299c595cfe..76d944ff38c 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/PropertyPageMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/PropertyPageMessages.properties @@ -28,9 +28,10 @@ CBreakpointPropertyPage.14=Expression to watch: CBreakpointPropertyPage.15=&Condition: CBreakpointPropertyPage.16=Invalid condition. CBreakpointPropertyPage.17=&Ignore count: -CBreakpointPropertyPage.18=Type: +CBreakpointPropertyPage.18=Class: CBreakpointPropertyPage.19=Enabled -CBreakpointPropertyPage.20=File: +CBreakpointPropertyPage.20=File: +CBreakpointPropertyPage.21=C/C++ Event Breakpoint ThreadFilterEditor.0=&Restrict to Selected Targets and Threads: SignalPropertyPage.0=Description: {0}. SignalPropertyPage.1=Pass this signal to the program. diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointUIContributionFactory.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointUIContributionFactory.java new file mode 100644 index 00000000000..5ad0e20c49b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointUIContributionFactory.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpoints; + +import java.util.ArrayList; +import java.util.Map; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IBreakpoint; + +public class CBreakpointUIContributionFactory { + private static final String EXTENSION_POINT_NAME = "breakpointContribution"; + private static final String MAIN_ELEMENT = "breakpointLabels"; + + private static CBreakpointUIContributionFactory instance; + protected ArrayList contributions; + + private CBreakpointUIContributionFactory() { + contributions = new ArrayList(); + loadSubtypeContributions(); + } + + /** + * + * @param breakpoint + * @return non-null array of ICBreakpointsUIContribution + * @throws CoreException if cannot get marker attributes from berakpoint + */ + public ICBreakpointsUIContribution[] getBreakpointUIContributions(IBreakpoint breakpoint) + throws CoreException { + String debugModelId = breakpoint.getModelIdentifier(); + String markerType = breakpoint.getMarker().getType(); + Map attributes = breakpoint.getMarker().getAttributes(); + return getBreakpointUIContributions(debugModelId, markerType, attributes); + } + + public ICBreakpointsUIContribution[] getBreakpointUIContributions(String debugModelId, + String breakpintMarkerType, Map attributes) { + ArrayList list = new ArrayList(); + for (ICBreakpointsUIContribution con : contributions) { + if (debugModelId == null || con.getDebugModelId() == null || debugModelId != null + && debugModelId.equals(con.getDebugModelId())) { + if (breakpintMarkerType != null && breakpintMarkerType.equals(con.getMarkerType())) { // TODO: handle marker inheritance? + + if (attributes == null || con.isApplicable(attributes)) { + list.add(con); + } + + } + } + + } + return list.toArray(new ICBreakpointsUIContribution[list.size()]); + } + + private void loadSubtypeContributions() { + + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint( + CDebugUIPlugin.getUniqueIdentifier(), EXTENSION_POINT_NAME); + if (ep == null) + return; + IConfigurationElement[] elements = ep.getConfigurationElements(); + for (int i = 0; i < elements.length; i++) { + IConfigurationElement configurationElement = elements[i]; + if (configurationElement.getName().equals(MAIN_ELEMENT)) { + String modelId = configurationElement.getAttribute("debugModelId"); + String markerType = getRequired(configurationElement, "markerType"); + if (markerType == null) + continue; + IConfigurationElement[] children = configurationElement.getChildren("attribute"); + for (IConfigurationElement att : children) { + + DefaultCBreakpointUIContribution adapter = new DefaultCBreakpointUIContribution(); + adapter.setMarkerType(markerType); + adapter.setDebugModelId(modelId); + if (processAttribute(att, adapter) == false) + continue; + + } + + } + } + } + + private boolean processAttribute(IConfigurationElement attrElement, + DefaultCBreakpointUIContribution adapter) { + String attrId = getRequired(attrElement, "name"); + String attrLabel = getRequired(attrElement, "label"); + String className = attrElement.getAttribute("fieldEditor"); + String type = attrElement.getAttribute("type"); + String svisible = attrElement.getAttribute("visible"); + + if (attrId == null) { + return false; + } + if (attrLabel == null) { + return false; + } + if (type == null) { + type = "string"; + } + boolean visible = true; + if (svisible != null && svisible.equalsIgnoreCase("false")) { + visible = false; + } + adapter.setId(attrId); + adapter.setLabel(attrLabel); + adapter.setControlClass(className); + adapter.setType(type); + adapter.setVisible(visible); + addContribution(adapter); + + IConfigurationElement[] children = attrElement.getChildren("value"); + for (IConfigurationElement value : children) { + processValue(value, adapter); + } + return true; + } + + private void processValue(IConfigurationElement valueElement, + DefaultCBreakpointUIContribution adapter) { + String valueId = getRequired(valueElement, "value"); + String valueLabel = getRequired(valueElement, "label"); + if (valueId == null) + return; + if (valueLabel == null) + return; + adapter.addValue(valueId, valueLabel); + IConfigurationElement[] children = valueElement.getChildren("attribute"); + for (IConfigurationElement att : children) { + DefaultCBreakpointUIContribution adapter2 = new DefaultCBreakpointUIContribution(); + // inherit values + adapter2.setMarkerType(adapter.getMarkerType()); + adapter2.setDebugModelId(adapter.getDebugModelId()); + adapter2.addContionsAll(adapter.getConditions()); + // add value condition + adapter2.addContionEquals(adapter.getId(), valueId); + if (processAttribute(att, adapter2) == false) + continue; + } + } + + public void addContribution(ICBreakpointsUIContribution contribution) { + contributions.add(contribution); + + } + + public static CBreakpointUIContributionFactory getInstance() { + if (instance == null) { + instance = new CBreakpointUIContributionFactory(); + } + return instance; + } + + private static String getRequired(IConfigurationElement configurationElement, String name) { + String elementValue = configurationElement.getAttribute(name); + if (elementValue == null) + CDebugUIPlugin.log(new Status(IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), + DebugPlugin.INTERNAL_ERROR, "Extension " + + configurationElement.getDeclaringExtension().getUniqueIdentifier() + + " missing required attribute: " + name, null)); + return elementValue; + } + +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CCatchpointsLabelProviderFactory.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CCatchpointsLabelProviderFactory.java new file mode 100644 index 00000000000..bf25402f25e --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CCatchpointsLabelProviderFactory.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpoints; + +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.core.DebugCoreMessages; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICCatchpoint; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.debug.internal.ui.model.elements.DebugElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.graphics.Image; + +/** + * Factory for event breakpoint label provider + */ +public class CCatchpointsLabelProviderFactory implements IAdapterFactory { + public static final String IMG_OBJS_CATCHPOINT_ENABLED = "icons/obj16/catchpoint_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CATCHPOINT_DISABLED = "icons/obj16/catchpointd_obj.gif"; //$NON-NLS-1$ + private static ILabelProvider fLabelProvider = new LabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof ICCatchpoint) { + try { + ICCatchpoint breakpoint = (ICCatchpoint) element; + + ICBreakpointsUIContribution bscs[] = CBreakpointUIContributionFactory.getInstance() + .getBreakpointUIContributions(breakpoint); + + if (bscs.length == 0) + return null; + StringBuffer buffer = new StringBuffer(""); + + for (ICBreakpointsUIContribution con : bscs) { + Object attValue = breakpoint.getMarker().getAttribute(con.getId()); + + if (con.getId().equals(ICCatchpoint.EVENT_TYPE_ID)) { + buffer.append(con.getLabelForValue((String) attValue)); + continue; + } + if (attValue != null && attValue.toString().length() > 0) { + buffer.append(" ["); + buffer.append(con.getLabel()); + buffer.append(": "); + if (attValue instanceof String) + buffer.append(con.getLabelForValue((String) attValue)); + else + buffer.append(attValue); + buffer.append("]"); + } + } + appendIgnoreCount(breakpoint, buffer); + appendCondition(breakpoint, buffer); + return buffer.toString(); + + } catch (CoreException e) { + CDebugUIPlugin.log(e); + } + } + return null; + } + + @Override + public Image getImage(Object element) { + try { + if (element instanceof ICCatchpoint) { + ICCatchpoint catchpoint = (ICCatchpoint) element; + if (catchpoint.isEnabled()) + return CDebugUIPlugin.getDefault().getImage(IMG_OBJS_CATCHPOINT_ENABLED); + else + return CDebugUIPlugin.getDefault().getImage(IMG_OBJS_CATCHPOINT_DISABLED); + } + } catch (CoreException e) { + CDebugUIPlugin.log(e); + } + return null; + } + }; + + protected static StringBuffer appendIgnoreCount(ICBreakpoint breakpoint, StringBuffer label) throws CoreException { + int ignoreCount = breakpoint.getIgnoreCount(); + if (ignoreCount > 0) { + label.append(' '); + label.append(MessageFormat.format( + DebugCoreMessages.getString("CDebugUtils.3"), new String[] { Integer.toString(ignoreCount) })); //$NON-NLS-1$ + } + return label; + } + + protected static void appendCondition(ICBreakpoint breakpoint, StringBuffer buffer) throws CoreException { + String condition = breakpoint.getCondition(); + if (condition != null && condition.length() > 0) { + buffer.append(' '); + buffer.append(MessageFormat + .format(DebugCoreMessages.getString("CDebugUtils.4"), new String[] { condition })); //$NON-NLS-1$ + } + } + + private static IElementLabelProvider fElementLabelProvider = new DebugElementLabelProvider() { + + protected String getLabel(TreePath elementPath, IPresentationContext context, String columnId) + throws CoreException { + + ICCatchpoint cp = (ICCatchpoint) elementPath.getLastSegment(); + return fLabelProvider.getText(cp); + + } + + }; + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, + * java.lang.Class) + */ + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (adapterType.equals(IElementLabelProvider.class)) { + if (adaptableObject instanceof ICCatchpoint) { + return fElementLabelProvider; + } + } + if (adapterType.equals(ILabelProvider.class)) { + if (adaptableObject instanceof ICCatchpoint) { + return fLabelProvider; + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + public Class[] getAdapterList() { + return new Class[] { IElementLabelProvider.class, ILabelProvider.class }; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java new file mode 100644 index 00000000000..20ec477aabb --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpoints; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.preferences.LabelFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.swt.widgets.Composite; + +class DefaultCBreakpointUIContribution implements ICBreakpointsUIContribution { + private String attLabel; + private String attId; + private String fieldEditorClassName; + private String markerType; + private String modelId; + private String attType; + private Map valueLabels = new LinkedHashMap(); + private Map conditions = new HashMap(); + + public String getId() { + return attId; + } + + public String getLabel() { + return attLabel; + } + + public String getDebugModelId() { + return modelId; + } + + static private Class[] fieldSignature = new Class[] { String.class, String.class, + Composite.class }; + + public FieldEditor getFieldEditor(String name, String labelText, Composite parent) { + String className = fieldEditorClassName; + if (fieldEditorClassName == null) { + className = LabelFieldEditor.class.getName(); + name = name+".valuelabel"; + } + try { + Class cclass = Class.forName(className); + Constructor constructor = cclass.getConstructor(fieldSignature); + FieldEditor editor = (FieldEditor) constructor.newInstance(name, labelText, parent); + return editor; + } catch (Exception e) { + // cannot happened, would have happened when loading extension + CDebugUIPlugin.log(e); + return null; + } + } + + public String getLabelForValue(String value) { + if (valueLabels.containsKey(value)) + return valueLabels.get(value); + return value; + } + + public String getMarkerType() { + return markerType; + } + + public String[] getPossibleValues() { + Set set = valueLabels.keySet(); + return set.toArray(new String[set.size()]); + } + + public String getType() { + return attType; + } + + public boolean isApplicable(Map properties) { + for (Object key : properties.keySet()) { + String value = conditions.get(key); + if (value != null) { + String realValue = (String) properties.get(key); + if (!value.equals(realValue)) { + return false; + } + } + } + return true; + } + + public void setLabel(String attLabel) { + this.attLabel = attLabel; + } + + public void setId(String attId) { + this.attId = attId; + } + + public void setControlClass(String controlClass) { + this.fieldEditorClassName = controlClass; + } + + public void setMarkerType(String markerId) { + this.markerType = markerId; + } + + public void setDebugModelId(String modelId) { + this.modelId = modelId; + } + + public void setType(String attType) { + this.attType = attType; + } + + public void addValue(String value, String valueLabel) { + valueLabels.put(value, valueLabel); + }; + + public void addContionEquals(String property, String value) { + conditions.put(property, value); + } + + public void setVisible(boolean visible) { + // TODO Auto-generated method stub + + } + + public Map getConditions() { + return conditions; + } + + public void addContionsAll(Map conditions2) { + conditions.putAll(conditions2); + } + + @Override + public String toString() { + return attId + " " + attLabel; + } +} \ No newline at end of file diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/ICBreakpointsUIContribution.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/ICBreakpointsUIContribution.java new file mode 100644 index 00000000000..7d701585708 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/ICBreakpointsUIContribution.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.breakpoints; + +import java.util.Map; + +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.swt.widgets.Composite; + + +public interface ICBreakpointsUIContribution { + + /** + * Attribute id + * @return + */ + public String getId(); + /** + * Extenralizable label for this attribute id + * @return + */ + public String getLabel(); + + /** + * Creates FieldEditor for given attribute or null if not needed + * @param name - property name, must be the same as breakpoint attribute + * @param labelText - text usually in front of field + * @param parent - parent composite + * @return ready to use FieldEditor + */ + public FieldEditor getFieldEditor(String name, String labelText, Composite parent); + + /** + * Return list of possible values that attributes can take, of null of no restrictions + * @return + */ + public String[] getPossibleValues(); + + /** + * Get label for given attribute value, externalizable string + * @param value + * @return + */ + public String getLabelForValue(String value); + + /** + * Get type of the attribute + * @return + */ + public String getType(); + + /** + * Get marker type for which this attribute is created + * @return + */ + public String getMarkerType(); + + /** + * Get debug model id + * @return + */ + public String getDebugModelId(); + + /** + * Return true if setting for an attribute applicable for setting of other attributes provided by the map + * @param map - contains pairs of attribute=value for other breakpoint attributes + * @return + */ + public boolean isApplicable(Map map); +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/preferences/LabelFieldEditor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/preferences/LabelFieldEditor.java new file mode 100644 index 00000000000..dbe23b4b384 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/preferences/LabelFieldEditor.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.preferences; + +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; + +public class LabelFieldEditor extends StringFieldEditor{ + public LabelFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + Text textControl = getTextControl(); + textControl.setEditable(false); + textControl.setBackground(parent.getBackground()); + } +}