diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
index 3294c5b1b1a..8008de53805 100644
--- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
+++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
@@ -7,6 +7,7 @@ Bundle-Activator: org.eclipse.cdt.debug.core.CDebugCorePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.cdt.debug.core,
+ org.eclipse.cdt.debug.core.breakpointactions,
org.eclipse.cdt.debug.core.cdi,
org.eclipse.cdt.debug.core.cdi.event,
org.eclipse.cdt.debug.core.cdi.model,
diff --git a/debug/org.eclipse.cdt.debug.core/plugin.properties b/debug/org.eclipse.cdt.debug.core/plugin.properties
index 7c79e03bdd2..84121e1d1ac 100644
--- a/debug/org.eclipse.cdt.debug.core/plugin.properties
+++ b/debug/org.eclipse.cdt.debug.core/plugin.properties
@@ -7,13 +7,15 @@
#
# Contributors:
# QNX Software Systems - Initial API and implementation
-# Ken Ryall (Nokia) - Added support for AbsoluteSourceContainer( 159833 )
-# Ken Ryall (Nokia) - Added support for breakpoint problems( 170027 )
+# Ken Ryall (Nokia) - Added support for AbsoluteSourceContainer( 159833 )
+# Ken Ryall (Nokia) - Added support for breakpoint problems( 170027 )
+# Ken Ryall (Nokia) - Added support for Breakpoint Actions ( 118308 )
###############################################################################
pluginName=C/C++ Development Tools Debug Model
providerName=Eclipse.org
CDebugger.name=C/C++ Development Tools Core Debugger Extension
+BreakpointAction.name=Breakpoint Action Extension
cLineBreakpoints.name=C/C++ Line Breakpoints
cAddressBreakpoints.name=C/C++ Address Breakpoints
diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml
index e8e5214c89e..92a842e1c1e 100644
--- a/debug/org.eclipse.cdt.debug.core/plugin.xml
+++ b/debug/org.eclipse.cdt.debug.core/plugin.xml
@@ -3,6 +3,7 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/debug/org.eclipse.cdt.debug.core/schema/BreakpointAction.exsd b/debug/org.eclipse.cdt.debug.core/schema/BreakpointAction.exsd
new file mode 100644
index 00000000000..7c5b6bac2b1
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/schema/BreakpointAction.exsd
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+ Extension to provide additional actions to execute when a breakpoint is hit.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Enter the first release in which this extension point appears.]
+
+
+
+
+
+
+
+
+ [Enter extension point usage example here.]
+
+
+
+
+
+
+
+
+ [Enter API information here.]
+
+
+
+
+
+
+
+
+ [Enter information about supplied implementation of this extension point.]
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java
index d0b6f77acb7..8bf3db754ca 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 QNX Software Systems and others.
+ * Copyright (c) 2004, 2007 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
@@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Ken Ryall (Nokia) - Support for breakpoint actions (bug 118308)
*******************************************************************************/
package org.eclipse.cdt.debug.core;
@@ -16,6 +17,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+
+import org.eclipse.cdt.debug.core.breakpointactions.BreakpointActionManager;
import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocation;
import org.eclipse.cdt.debug.internal.core.DebugConfiguration;
import org.eclipse.cdt.debug.internal.core.ICDebugInternalConstants;
@@ -69,6 +72,13 @@ public class CDebugCorePlugin extends Plugin {
*/
private ListenerList fBreakpointListeners;
+ /**
+ * Breakpoint action manager.
+ */
+ private BreakpointActionManager breakpointActionManager;
+
+ public static final String BREAKPOINT_ACTION_SIMPLE_ID = "BreakpointActionType"; //$NON-NLS-1$
+
/**
* Dummy source lookup director needed to manage common source containers.
*/
@@ -312,6 +322,8 @@ public class CDebugCorePlugin extends Plugin {
* @return the list of breakpoint listeners registered with this plugin
*/
public Object[] getCBreakpointListeners() {
+ if (fBreakpointListeners == null)
+ return new Object[0];
return fBreakpointListeners.getListeners();
}
@@ -393,4 +405,11 @@ public class CDebugCorePlugin extends Plugin {
fDebugConfigurations = null;
}
}
+
+ public BreakpointActionManager getBreakpointActionManager() {
+ if (breakpointActionManager == null)
+ breakpointActionManager = new BreakpointActionManager();
+ return breakpointActionManager;
+ }
+
}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/AbstractBreakpointAction.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/AbstractBreakpointAction.java
new file mode 100644
index 00000000000..a75f327f8c7
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/AbstractBreakpointAction.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+import org.eclipse.core.runtime.PlatformObject;
+
+public abstract class AbstractBreakpointAction extends PlatformObject implements IBreakpointAction {
+
+ private String actionName;
+
+ public String getName() {
+ return actionName;
+ }
+
+ public void setName(String name) {
+ actionName = name;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionAdapterFactory.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionAdapterFactory.java
new file mode 100644
index 00000000000..61ff2caf764
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionAdapterFactory.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+import org.eclipse.cdt.debug.internal.core.model.CThread;
+import org.eclipse.core.runtime.IAdapterFactory;
+
+public class BreakpointActionAdapterFactory implements IAdapterFactory {
+
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (adapterType.equals(ILogActionEnabler.class)) {
+ if (adaptableObject instanceof CThread) {
+ return new LogActionEnabler((CThread) adaptableObject);
+ }
+ }
+ if (adapterType.equals(IResumeActionEnabler.class)) {
+ if (adaptableObject instanceof CThread) {
+ return new ResumeActionEnabler((CThread) adaptableObject);
+ }
+ }
+ return null;
+ }
+
+ public Class[] getAdapterList() {
+ return new Class[] { ILogActionEnabler.class, IResumeActionEnabler.class, };
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionManager.java
new file mode 100644
index 00000000000..b2a93c9d6fd
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionManager.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+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.debug.core.CDebugCorePlugin;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.model.IBreakpoint;
+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;
+
+public class BreakpointActionManager {
+
+ public static final String BREAKPOINT_ACTION_ATTRIBUTE = "BREAKPOINT_ACTIONS"; //$NON-NLS-1$
+ private static final String BREAKPOINT_ACTION_DATA = "BreakpointActionManager.actionData"; //$NON-NLS-1$
+
+ private IExtension[] breakpointActionExtensions = null;
+ private ArrayList breakpointActions = null;
+
+ public BreakpointActionManager() {
+ }
+
+ public void addAction(IBreakpointAction action) {
+ getBreakpointActions().add(action);
+ }
+
+ private IBreakpointAction createActionFromClassName(String name, String className) {
+
+ IBreakpointAction action = null;
+ IExtension[] actionExtensions = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActionExtensions();
+
+ try {
+
+ for (int i = 0; i < actionExtensions.length && action == null; i++) {
+ IConfigurationElement[] elements = actionExtensions[i].getConfigurationElements();
+ for (int j = 0; j < elements.length && action == null; j++) {
+
+ if (elements[j].getAttribute("class").equals(className)) { //$NON-NLS-1$
+ action = (IBreakpointAction) elements[j].createExecutableExtension("class"); //$NON-NLS-1$
+ action.setName(name);
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().addAction(action);
+ }
+ }
+ }
+
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+
+ return action;
+ }
+
+ public void deleteAction(IBreakpointAction action) {
+ getBreakpointActions().remove(action);
+ }
+
+ public void executeActions(IBreakpoint breakpoint, IAdaptable context) {
+
+ if (breakpoint != null) {
+ IMarker marker = breakpoint.getMarker();
+ String actionNames = marker.getAttribute(BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$
+ StringTokenizer tok = new StringTokenizer(actionNames, ","); //$NON-NLS-1$
+ while (tok.hasMoreTokens()) {
+ String actionName = tok.nextToken();
+ IBreakpointAction action = findBreakpointAction(actionName);
+ if (action != null) {
+ action.execute(breakpoint, context);
+ }
+ }
+ }
+ }
+
+ public IBreakpointAction findBreakpointAction(String name) {
+ for (Iterator iter = getBreakpointActions().iterator(); iter.hasNext();) {
+ IBreakpointAction action = (IBreakpointAction) iter.next();
+ if (action.getName().equals(name))
+ return action;
+ }
+ return null;
+ }
+
+ public IExtension[] getBreakpointActionExtensions() {
+ if (breakpointActionExtensions == null) {
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CDebugCorePlugin.PLUGIN_ID, CDebugCorePlugin.BREAKPOINT_ACTION_SIMPLE_ID);
+ if (point == null)
+ breakpointActionExtensions = new IExtension[0];
+ else {
+ breakpointActionExtensions = point.getExtensions();
+ }
+ }
+
+ return breakpointActionExtensions;
+ }
+
+ public ArrayList getBreakpointActions() {
+ if (breakpointActions == null) {
+ breakpointActions = new ArrayList();
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().loadActionData();
+ }
+ return breakpointActions;
+ }
+
+ private void loadActionData() {
+
+ String actionData = CDebugCorePlugin.getDefault().getPluginPreferences().getString(BREAKPOINT_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();
+
+ IBreakpointAction action = createActionFromClassName(name, className);
+ action.initializeFromMemento(value);
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String makeUniqueActionName(String defaultName) {
+ String result = defaultName;
+ IBreakpointAction action = findBreakpointAction(defaultName);
+ int actionCount = 1;
+ while (action != null) {
+ result = defaultName + "(" + actionCount + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ action = findBreakpointAction(result);
+ actionCount++;
+ }
+ return result;
+ }
+
+ public void revertActionData() {
+ breakpointActions = 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("breakpointActionData"); //$NON-NLS-1$
+ doc.appendChild(rootElement);
+
+ for (Iterator iter = getBreakpointActions().iterator(); iter.hasNext();) {
+ IBreakpointAction action = (IBreakpointAction) 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();
+ }
+ CDebugCorePlugin.getDefault().getPluginPreferences().setValue(BREAKPOINT_ACTION_DATA, actionData);
+ CDebugCorePlugin.getDefault().savePluginPreferences();
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IBreakpointAction.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IBreakpointAction.java
new file mode 100644
index 00000000000..d7f35c45338
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IBreakpointAction.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+/**
+ * Interface implemented by plug-ins that wish to contribute breakpoint actions.
+ *
+ * THIS INTERFACE IS PROVISIONAL AND WILL CHANGE IN THE FUTURE BREAKPOINT ACTION
+ * CONTRIBUTIONS USING THIS INTERFACE WILL NEED TO BE REVISED TO WORK WITH
+ * FUTURE VERSIONS OF CDT.
+ *
+ */
+public interface IBreakpointAction {
+
+ public void execute(IBreakpoint breakpoint, IAdaptable context);
+
+ public String getMemento();
+
+ public void initializeFromMemento(String data);
+
+ public String getDefaultName();
+
+ public String getSummary();
+
+ public String getTypeName();
+
+ public String getIdentifier();
+
+ public String getName();
+
+ public void setName(String name);
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ILogActionEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ILogActionEnabler.java
new file mode 100644
index 00000000000..80e53fe787e
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ILogActionEnabler.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+/**
+ *
+ * THIS INTERFACE IS PROVISIONAL AND WILL CHANGE IN THE FUTURE PLUG-INS USING
+ * THIS INTERFACE WILL NEED TO BE REVISED TO WORK WITH FUTURE VERSIONS OF CDT.
+ *
+ */
+
+public interface ILogActionEnabler {
+
+ String evaluateExpression(String expression) throws Exception;
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IResumeActionEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IResumeActionEnabler.java
new file mode 100644
index 00000000000..19489eab2b1
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IResumeActionEnabler.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+/**
+ *
+ * THIS INTERFACE IS PROVISIONAL AND WILL CHANGE IN THE FUTURE PLUG-INS USING
+ * THIS INTERFACE WILL NEED TO BE REVISED TO WORK WITH FUTURE VERSIONS OF CDT.
+ *
+ */
+
+public interface IResumeActionEnabler {
+
+ void resume() throws Exception;
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/LogActionEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/LogActionEnabler.java
new file mode 100644
index 00000000000..05aa75e2c51
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/LogActionEnabler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+import java.util.List;
+
+import org.eclipse.cdt.debug.internal.core.model.CStackFrame;
+import org.eclipse.cdt.debug.internal.core.model.CThread;
+
+public class LogActionEnabler implements ILogActionEnabler {
+
+ private CThread thread;
+
+ public LogActionEnabler(CThread thread) {
+ this.thread = thread;
+ }
+
+ public String evaluateExpression(String expression) throws Exception {
+ List frames = thread.computeStackFrames();
+ CStackFrame frame = (CStackFrame) frames.get(0);
+
+ return frame.evaluateExpressionToString(expression);
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ResumeActionEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ResumeActionEnabler.java
new file mode 100644
index 00000000000..d5e2860c0bd
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ResumeActionEnabler.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.debug.core.breakpointactions;
+
+import org.eclipse.cdt.debug.internal.core.model.CThread;
+
+public class ResumeActionEnabler implements IResumeActionEnabler {
+
+ private CThread thread;
+
+ public ResumeActionEnabler(CThread adaptableObject) {
+ thread = adaptableObject;
+ }
+
+ public void resume() throws Exception {
+ thread.resume();
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java
index 625fee38f20..6f521d61d4a 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 QNX Software Systems and others.
+ * Copyright (c) 2000, 2007 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
@@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Stefan Bylund (Enea, steby@enea.se) - patch for bug 155464
+ * Ken Ryall (Nokia) - Support for breakpoint actions (bug 118308)
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.model;
@@ -16,6 +17,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDIBreakpointHit;
import org.eclipse.cdt.debug.core.cdi.ICDIEndSteppingRange;
@@ -29,7 +32,6 @@ import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent;
import org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener;
import org.eclipse.cdt.debug.core.cdi.event.ICDIResumedEvent;
import org.eclipse.cdt.debug.core.cdi.event.ICDISuspendedEvent;
-import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint;
import org.eclipse.cdt.debug.core.cdi.model.ICDIObject;
import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration;
@@ -678,8 +680,8 @@ public class CThread extends CDebugElement implements ICThread, IRestart, IResum
if ( reason instanceof ICDIEndSteppingRange ) {
handleEndSteppingRange( (ICDIEndSteppingRange)reason );
}
- else if ( reason instanceof ICDIBreakpoint ) {
- handleBreakpointHit( (ICDIBreakpoint)reason );
+ else if ( reason instanceof ICDIBreakpointHit ) {
+ handleBreakpointHit( (ICDIBreakpointHit)reason );
}
else if ( reason instanceof ICDISignalReceived ) {
handleSuspendedBySignal( (ICDISignalReceived)reason );
@@ -726,7 +728,10 @@ public class CThread extends CDebugElement implements ICThread, IRestart, IResum
fireSuspendEvent( DebugEvent.STEP_END );
}
- private void handleBreakpointHit( ICDIBreakpoint breakpoint ) {
+ private void handleBreakpointHit( ICDIBreakpointHit breakpointHit ) {
+ IBreakpoint platformBreakpoint = ((CDebugTarget)getDebugTarget()).getBreakpointManager().getBreakpoint(breakpointHit.getBreakpoint());
+ if (platformBreakpoint != null)
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().executeActions(platformBreakpoint, this);
fireSuspendEvent( DebugEvent.BREAKPOINT );
}
@@ -925,8 +930,8 @@ public class CThread extends CDebugElement implements ICThread, IRestart, IResum
if ( reason instanceof ICDIEndSteppingRange ) {
handleEndSteppingRange( (ICDIEndSteppingRange)reason );
}
- else if ( reason instanceof ICDIBreakpoint ) {
- handleBreakpointHit( (ICDIBreakpoint)reason );
+ else if ( reason instanceof ICDIBreakpointHit ) {
+ handleBreakpointHit( (ICDIBreakpointHit)reason );
}
else if ( reason instanceof ICDISignalReceived ) {
handleSuspendedBySignal( (ICDISignalReceived)reason );
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties
index 50cef95140e..384b375ff21 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.properties
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties
@@ -21,6 +21,7 @@ MemoryPreferencePage.name=Memory View
CDebugPreferencePage.name=Debug
SourcePreferencePage.name=Common Source Lookup Path
DebuggerTypesPreferencePage.name=Debugger Types
+BreakpointActionPage.name=Breakpoint Action UI Page
RunMenu.label=&Run
DebugActionSet.label=C/C++ Debug
@@ -139,3 +140,10 @@ RestoredefaultRegisterGroupsAction.tooltip=Restore Default Register Groups
importCPPCategory.name=C/C++
importExecutableWizard.name=C/C++ Executable
importExecutableWizard.description=Imports a C/C++ executable file. Will create a project and launch configuration for debugging.
+
+BreakpointActionsPage.label=Actions
+BreakpointActionsPrefPage.label=Breakpoint Actions
+SoundAction.name=Sound Action
+LogAction.name=Log Action
+ResumeAction.name=Resume Action
+ExternalToolAction.name=External Tool Action
\ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml
index bcdfc69ef2a..b96266e1214 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.xml
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml
@@ -3,6 +3,7 @@
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This extension point provides a mechanism for contributing UI to define and edit a breakpoint action.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.1
+
+
+
+
+
+
+
+
+ [Enter extension point usage example here.]
+
+
+
+
+
+
+
+
+ Value of the attribute class must be a fully qualified name of a Java class that implements the interface org.eclipse.cdt.debug.ui.ICDebuggerPage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionDialog.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionDialog.java
new file mode 100644
index 00000000000..5e78d2f2fd5
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionDialog.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class ActionDialog extends Dialog {
+
+ public static final String BREAKPOINT_ACTION_PAGE_SIMPLE_ID = "breakpointActionPage"; //$NON-NLS-1$
+
+ private static final String ACTION_DIALOG_LAST_SELECTED = "ActionDialog.lastSelectedAction"; //$NON-NLS-1$
+
+ private Composite actionArea;
+ private Composite[] actionComposites;
+ private IBreakpointAction breakpointAction;
+ private IBreakpointActionPage actionPage;
+ private IBreakpointAction[] breakpointActions;
+ private IBreakpointActionPage[] actionPages;
+ private String actionName;
+ private Text actionNameTextWidget;
+ private Combo combo;
+ private Composite dialogArea;
+ private int lastSelectedActionTypeIndex;
+ private IBreakpointAction originalAction;
+
+ private IExtension[] breakpointActionPageExtensions;
+
+ /**
+ * Create the dialog
+ *
+ * @param parentShell
+ */
+ public ActionDialog(Shell parentShell, IBreakpointAction action) {
+ super(parentShell);
+ setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
+ this.originalAction = action;
+ this.breakpointAction = action;
+ lastSelectedActionTypeIndex = 0;
+ }
+
+ protected void cancelPressed() {
+ actionPage.actionDialogCanceled();
+ super.cancelPressed();
+ }
+
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ if (originalAction == null)
+ newShell.setText(Messages.getString("ActionDialog.0")); //$NON-NLS-1$
+ else
+ newShell.setText(originalAction.getName());
+ }
+
+ /**
+ * Create contents of the button bar
+ *
+ * @param parent
+ */
+ 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
+ *
+ * @param parent
+ */
+ 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(Messages.getString("ActionDialog.1")); //$NON-NLS-1$
+
+ 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(Messages.getString("ActionDialog.2")); //$NON-NLS-1$
+
+ combo = new Combo(dialogArea, SWT.READ_ONLY);
+ combo.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent e) {
+ try {
+ showActionComposite();
+ } catch (CoreException e1) {
+ }
+ }
+ });
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ //
+
+ IExtension[] actionExtensions = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActionExtensions();
+
+ breakpointActions = new IBreakpointAction[actionExtensions.length];
+ actionPages = new IBreakpointActionPage[actionExtensions.length];
+ actionComposites = new Composite[actionExtensions.length];
+
+ if (actionExtensions.length > 0) {
+
+ String lastTypeName = CDebugUIPlugin.getDefault().getPreferenceStore().getString(ACTION_DIALOG_LAST_SELECTED);
+
+ if (breakpointAction != null) {
+ lastTypeName = breakpointAction.getTypeName();
+ actionName = breakpointAction.getName();
+ }
+
+ for (int i = 0; i < actionExtensions.length; i++) {
+ IConfigurationElement[] elements = actionExtensions[i].getConfigurationElements();
+ for (int j = 0; j < elements.length; j++) {
+ String actionTypeName = elements[j].getAttribute("name"); //$NON-NLS-1$
+ combo.add(actionTypeName);
+ if (actionTypeName.equals(lastTypeName))
+ lastSelectedActionTypeIndex = i;
+ }
+ }
+
+ combo.select(lastSelectedActionTypeIndex);
+ if (originalAction != null)
+ combo.setEnabled(false);
+
+ breakpointActions[combo.getSelectionIndex()] = breakpointAction;
+
+ 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) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ return dialogArea;
+ }
+
+ public IBreakpointAction getBreakpointAction() {
+ return breakpointAction;
+ }
+
+ public String getActionName() {
+ return actionName;
+ }
+
+ /**
+ * Return the initial size of the dialog
+ */
+ protected Point getInitialSize() {
+ return new Point(500, 375);
+ }
+
+ protected void okPressed() {
+ if (originalAction == null)
+ CDebugUIPlugin.getDefault().getPreferenceStore().setValue(ACTION_DIALOG_LAST_SELECTED, breakpointAction.getTypeName());
+ String newName = actionNameTextWidget.getText();
+ if (originalAction == null || !originalAction.getName().equals(newName)) {
+ actionName = CDebugCorePlugin.getDefault().getBreakpointActionManager().makeUniqueActionName(newName);
+ breakpointAction.setName(actionName);
+ }
+ actionPage.actionDialogOK();
+ super.okPressed();
+ }
+
+ void showActionComposite() throws CoreException {
+ // Find the selected extension
+ int selectedTypeIndex = combo.getSelectionIndex();
+ lastSelectedActionTypeIndex = selectedTypeIndex;
+ breakpointAction = breakpointActions[selectedTypeIndex];
+ if (breakpointAction == null) {
+ int elementCount = 0;
+ IConfigurationElement selectedElement = null;
+
+ IExtension[] actionExtensions = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActionExtensions();
+
+ for (int i = 0; i < actionExtensions.length && selectedElement == null; i++) {
+ IConfigurationElement[] elements = actionExtensions[i].getConfigurationElements();
+ for (int j = 0; j < elements.length && selectedElement == null; j++) {
+ if (elementCount == selectedTypeIndex)
+ selectedElement = elements[j];
+ elementCount++;
+ }
+ }
+
+ breakpointAction = (IBreakpointAction) selectedElement.createExecutableExtension("class"); //$NON-NLS-1$
+ breakpointAction.setName(breakpointAction.getDefaultName());
+ breakpointActions[selectedTypeIndex] = breakpointAction;
+ }
+ actionPage = actionPages[selectedTypeIndex];
+ if (actionPage == null) {
+ actionPages[selectedTypeIndex] = getActionPage(breakpointActions[selectedTypeIndex]);
+ actionPage = actionPages[selectedTypeIndex];
+ }
+ if (actionComposites[selectedTypeIndex] == null) {
+ Composite actionComposite = actionPages[selectedTypeIndex].createComposite(breakpointAction, actionArea, SWT.NONE);
+ actionComposites[selectedTypeIndex] = actionComposite;
+ }
+ actionName = breakpointAction.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_SIMPLE_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++) {
+
+ if (elements[j].getAttribute("actionType").equals(breakpointAction.getIdentifier())) { //$NON-NLS-1$
+ actionPageResult = (IBreakpointActionPage) elements[j].createExecutableExtension("class"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return actionPageResult;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsList.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsList.java
new file mode 100644
index 00000000000..d7345aae7ef
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsList.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+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;
+
+public class ActionsList extends Composite {
+
+ private Button removeButton;
+ private Table table;
+
+ public ActionsList(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() {
+ public void widgetSelected(SelectionEvent e) {
+ updateButtons();
+ }
+ });
+
+ final TableColumn nameTableColumn = new TableColumn(table, SWT.NONE);
+ nameTableColumn.setWidth(120);
+ nameTableColumn.setText(Messages.getString("ActionsList.0")); //$NON-NLS-1$
+
+ final TableColumn typeTableColumn = new TableColumn(table, SWT.NONE);
+ typeTableColumn.setWidth(120);
+ typeTableColumn.setText(Messages.getString("ActionsList.1")); //$NON-NLS-1$
+
+ final TableColumn summaryTableColumn = new TableColumn(table, SWT.NONE);
+ summaryTableColumn.setWidth(120);
+ summaryTableColumn.setText(Messages.getString("ActionsList.2")); //$NON-NLS-1$
+
+ removeButton = new Button(this, SWT.NONE);
+ removeButton.setText(Messages.getString("ActionsList.3")); //$NON-NLS-1$
+
+ removeButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ HandleRemoveButton();
+ }
+ });
+
+ final Button upButton = new Button(this, SWT.NONE);
+ upButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent e) {
+ HandleUpButton();
+ }
+ });
+ upButton.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END));
+ upButton.setText(Messages.getString("ActionsList.4")); //$NON-NLS-1$
+
+ final Button downButton = new Button(this, SWT.NONE);
+ downButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent e) {
+ HandleDownButton();
+ }
+ });
+ downButton.setText(Messages.getString("ActionsList.5")); //$NON-NLS-1$
+ //
+
+ updateButtons();
+ }
+
+ public void addAction(IBreakpointAction action) {
+ TableItem[] currentItems = table.getItems();
+ boolean alreadyInList = false;
+ for (int i = 0; i < currentItems.length && !alreadyInList; i++) {
+ alreadyInList = ((IBreakpointAction) currentItems[i].getData()).equals(action);
+ }
+ 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 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(((IBreakpointAction) 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();
+ StringTokenizer tok = new StringTokenizer(actionNames, ","); //$NON-NLS-1$
+
+ while (tok.hasMoreTokens()) {
+ String actionName = tok.nextToken();
+ IBreakpointAction action = CDebugCorePlugin.getDefault().getBreakpointActionManager().findBreakpointAction(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() {
+ TableItem[] selectedItems = table.getSelection();
+ removeButton.setEnabled(selectedItems.length > 0);
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPreferencePage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPreferencePage.java
new file mode 100644
index 00000000000..2278ddf0417
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPreferencePage.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+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;
+
+public class ActionsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private String contextHelpID = "breakpoint_actions_page_help"; //$NON-NLS-1$
+
+ public ActionsPreferencePage() {
+ super();
+ setPreferenceStore(CDebugUIPlugin.getDefault().getPreferenceStore());
+ }
+
+ 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(Messages.getString("ActionsPreferencePage.0")); //$NON-NLS-1$
+ final GlobalActionsList actionsList = new GlobalActionsList(container, SWT.NONE, false);
+ actionsList.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+
+ String helpContextID = CDebugUIPlugin.PLUGIN_ID + "." + contextHelpID; //$NON-NLS-1$
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(super.getControl(), helpContextID);
+
+ return container;
+ }
+
+ public void init(IWorkbench workbench) {
+ }
+
+ public boolean performCancel() {
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().revertActionData();
+ return super.performCancel();
+ }
+
+ public boolean performOk() {
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().saveActionData();
+ return super.performOk();
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPropertyPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPropertyPage.java
new file mode 100644
index 00000000000..821bb1abe2a
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPropertyPage.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.core.breakpointactions.BreakpointActionManager;
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+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;
+
+public class ActionsPropertyPage extends PropertyPage {
+
+ private ActionsList actionsList;
+ private IMarker breakpointMarker;
+ private GlobalActionsList globalActionsList;
+ private String savedActionNames;
+
+ public ActionsPropertyPage() {
+ super();
+ }
+
+ public Control createContents(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+
+ IBreakpoint breakpoint = (IBreakpoint) this.getElement().getAdapter(org.eclipse.debug.core.model.IBreakpoint.class);
+ breakpointMarker = breakpoint.getMarker();
+ savedActionNames = breakpointMarker.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(Messages.getString("ActionsPropertyPage.1")); //$NON-NLS-1$
+
+ actionsList = new ActionsList(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(Messages.getString("ActionsPropertyPage.2")); //$NON-NLS-1$
+
+ globalActionsList = new GlobalActionsList(container, SWT.NONE, true);
+ final GridData gridData_1 = new GridData(GridData.FILL_BOTH);
+ gridData_1.horizontalSpan = 2;
+ globalActionsList.setLayoutData(gridData_1);
+ //
+
+ String actionNames = breakpointMarker.getAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$
+ actionsList.setNames(actionNames);
+
+ globalActionsList.getAttachButton().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ HandleAttachButton();
+ }
+ });
+
+ return container;
+ }
+
+ protected void HandleAttachButton() {
+
+ IBreakpointAction[] selectedActions = globalActionsList.getSelectedActions();
+ for (int i = 0; i < selectedActions.length; i++) {
+ actionsList.addAction(selectedActions[i]);
+ }
+ }
+
+ protected void performDefaults() {
+ try {
+ breakpointMarker.setAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, ""); //$NON-NLS-1$
+ actionsList.setNames(""); //$NON-NLS-1$
+ } catch (CoreException e) {
+ }
+ super.performDefaults();
+ }
+
+ public boolean performCancel() {
+ try {
+ breakpointMarker.setAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, savedActionNames);
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().revertActionData();
+ } catch (CoreException e) {
+ }
+ return super.performCancel();
+ }
+
+ public boolean performOk() {
+ try {
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().saveActionData();
+ breakpointMarker.setAttribute(BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, actionsList.getActionNames());
+ } catch (CoreException e) {
+ }
+ return super.performOk();
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolAction.java
new file mode 100644
index 00000000000..60c71e8de04
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolAction.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+import java.text.MessageFormat;
+
+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.debug.core.breakpointactions.AbstractBreakpointAction;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.DebugUITools;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class ExternalToolAction extends AbstractBreakpointAction {
+
+ private String externalToolName = new String(""); //$NON-NLS-1$
+
+ public void execute(IBreakpoint breakpoint, IAdaptable context) {
+ ILaunchManager lcm = DebugPlugin.getDefault().getLaunchManager();
+ try {
+ ILaunchConfiguration[] launchConfigurations = lcm.getLaunchConfigurations();
+ for (int i = 0; i < launchConfigurations.length; i++) {
+ if (launchConfigurations[i].getName().equals(externalToolName)) {
+ DebugUITools.launch(launchConfigurations[i], ILaunchManager.RUN_MODE);
+ }
+ }
+ } catch (CoreException e) {
+ }
+
+ }
+
+ public String getDefaultName() {
+ return "Untitled External Tool Action"; //$NON-NLS-1$
+ }
+
+ public String getExternalToolName() {
+ return externalToolName;
+ }
+
+ public void setExternalToolName(String launchConfigName) {
+ this.externalToolName = launchConfigName;
+ }
+
+ public String getIdentifier() {
+ return "org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolAction"; //$NON-NLS-1$
+ }
+
+ public String getMemento() {
+ String executeData = new String(""); //$NON-NLS-1$
+ if (externalToolName != null) {
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("launchConfigName"); //$NON-NLS-1$
+ rootElement.setAttribute("configName", externalToolName); //$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);
+
+ executeData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return executeData;
+ }
+
+ public String getSummary() {
+ return MessageFormat.format(Messages.getString("ExternalToolAction.Summary"), new Object[] { externalToolName }); //$NON-NLS-1$
+ }
+
+ public String getTypeName() {
+ return Messages.getString("ExternalToolAction.TypeName"); //$NON-NLS-1$
+ }
+
+ 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();
+ String value = root.getAttribute("configName"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ externalToolName = value;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionComposite.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionComposite.java
new file mode 100644
index 00000000000..c179131bccb
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionComposite.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+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.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.activities.WorkbenchActivityHelper;
+import org.eclipse.ui.dialogs.ListDialog;
+
+public class ExternalToolActionComposite extends Composite {
+
+ /**
+ * A plug-in contribution (UI element) which contains a launch configuration
+ * type (Core element). Plug-in contributions are passed to the workbench
+ * activity support to filter elements from the UI.
+ */
+ class LaunchConfigurationTypeContribution implements IPluginContribution {
+
+ protected ILaunchConfigurationType type;
+
+ /**
+ * Creates a new plug-in contribution for the given type
+ *
+ * @param type
+ * the launch configuration type
+ */
+ public LaunchConfigurationTypeContribution(ILaunchConfigurationType type) {
+ this.type = type;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IPluginContribution#getLocalId()
+ */
+ public String getLocalId() {
+ return type.getIdentifier();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IPluginContribution#getPluginId()
+ */
+ public String getPluginId() {
+ return type.getPluginIdentifier();
+ }
+
+ }
+
+ public class LaunchConfigurationSelectionDialog extends ListDialog {
+
+ private ILaunchConfiguration[] launchConfigs;
+
+ public LaunchConfigurationSelectionDialog(ExternalToolActionComposite composite, ILaunchConfiguration[] lcs) {
+ super(composite.getShell());
+
+ launchConfigs = lcs;
+
+ this.setInput(composite);
+ this.setContentProvider(new IStructuredContentProvider() {
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public void dispose() {
+ }
+
+ public Object[] getElements(Object parent) {
+ return launchConfigs;
+ }
+ });
+
+ this.setLabelProvider(new LabelProvider() {
+
+ public String getText(Object element) {
+ return ((ILaunchConfiguration) element).getName();
+ }
+ });
+ }
+
+ }
+
+ private Text extToolName;
+
+ /**
+ * Create the composite
+ *
+ * @param parent
+ * @param style
+ * @param page
+ */
+ public ExternalToolActionComposite(Composite parent, int style, ExternalToolActionPage page) {
+ super(parent, style);
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 3;
+ setLayout(gridLayout);
+
+ final Label executeFileLabel = new Label(this, SWT.LEFT);
+ executeFileLabel.setLayoutData(new GridData());
+ executeFileLabel.setText(Messages.getString("ExternalToolActionComposite.ToolLabel")); //$NON-NLS-1$
+
+ extToolName = new Text(this, SWT.READ_ONLY);
+ extToolName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ extToolName.setText(page.getExternalToolAction().getExternalToolName());
+
+ final ExternalToolActionComposite externalToolActionComposite = this;
+
+ final Button browseButton = new Button(this, SWT.NONE);
+ browseButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+
+ ILaunchConfiguration[] lcs = getLaunchConfigurations();
+ LaunchConfigurationSelectionDialog dlg = new LaunchConfigurationSelectionDialog(externalToolActionComposite, lcs);
+ dlg.setTitle(Messages.getString("ExternalToolActionComposite.DialogTitle")); //$NON-NLS-1$
+ dlg.setMessage(Messages.getString("ExternalToolActionComposite.DialogMessage")); //$NON-NLS-1$
+ if (lcs.length > 0) {
+ ILaunchConfiguration[] initialSelection = new ILaunchConfiguration[1];
+ String existingName = extToolName.getText();
+ initialSelection[0] = lcs[0];
+ if (existingName.length() > 0) {
+ for (int i = 0; i < lcs.length; i++) {
+ if (lcs[i].getName().equals(existingName)) {
+ initialSelection[0] = lcs[i];
+ break;
+ }
+ }
+ }
+ dlg.setInitialSelections(initialSelection);
+ }
+ dlg.setAddCancelButton(false);
+
+ if (dlg.open() == Window.OK) {
+ Object[] selectedTool = dlg.getResult();
+ if (selectedTool.length > 0 && selectedTool[0] instanceof ILaunchConfiguration) {
+ externalToolActionComposite.setExternalToolName(((ILaunchConfiguration) selectedTool[0]).getName());
+ }
+ }
+
+ }
+ });
+ browseButton.setText(Messages.getString("ExternalToolActionComposite.ChooseButtonTitle")); //$NON-NLS-1$
+ browseButton.setEnabled(getLaunchConfigurations().length > 0);
+
+ final Button externalToolsButton = new Button(this, SWT.NONE);
+ externalToolsButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ DebugUITools.openLaunchConfigurationDialogOnGroup(externalToolActionComposite.getShell(), new StructuredSelection(), "org.eclipse.ui.externaltools.launchGroup"); //$NON-NLS-1$
+ browseButton.setEnabled(getLaunchConfigurations().length > 0);
+ }
+ });
+ externalToolsButton.setText(Messages.getString("ExternalToolActionComposite.ExternalToolsButtonTitle")); //$NON-NLS-1$
+ //
+ }
+
+ protected void setExternalToolName(String externalToolName) {
+ extToolName.setText(externalToolName);
+ }
+
+ private boolean equalCategories(String c1, String c2) {
+ if (c1 == null || c2 == null) {
+ return c1 == c2;
+ }
+ return c1.equals(c2);
+ }
+
+ public ILaunchConfiguration[] getLaunchConfigurations() {
+ ArrayList onlyExternalTools = new ArrayList();
+ ILaunchManager lcm = DebugPlugin.getDefault().getLaunchManager();
+ ILaunchConfiguration[] launchConfigurations = new ILaunchConfiguration[0];
+ try {
+ launchConfigurations = lcm.getLaunchConfigurations();
+ for (int i = 0; i < launchConfigurations.length; i++) {
+
+ ILaunchConfiguration config = launchConfigurations[i];
+ ILaunchConfigurationType type = config.getType();
+ boolean priv = false;
+ if (config != null) {
+ try {
+ priv = config.getAttribute(IDebugUIConstants.ATTR_PRIVATE, false);
+ } catch (CoreException e) {
+ }
+ }
+ if (type != null) {
+ if (!priv && type.supportsMode(ILaunchManager.RUN_MODE) && equalCategories(type.getCategory(), "org.eclipse.ui.externaltools") //$NON-NLS-1$ //$NON-NLS-2$
+ && !WorkbenchActivityHelper.filterItem(new LaunchConfigurationTypeContribution(type)))
+ onlyExternalTools.add(launchConfigurations[i]);
+ }
+
+ }
+ } catch (CoreException e) {
+ }
+ return (ILaunchConfiguration[]) onlyExternalTools.toArray(new ILaunchConfiguration[onlyExternalTools.size()]);
+ }
+
+ public void dispose() {
+ super.dispose();
+ }
+
+ protected void checkSubclass() {
+ // Disable the check that prevents subclassing of SWT components
+ }
+
+ public String getLaunchConfigName() {
+ return extToolName.getText();
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionPage.java
new file mode 100644
index 00000000000..3e82bc3363d
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionPage.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.swt.widgets.Composite;
+
+public class ExternalToolActionPage extends PlatformObject implements IBreakpointActionPage {
+
+ private ExternalToolAction externalToolAction;
+ private ExternalToolActionComposite runComposite;
+
+ public void actionDialogCanceled() {
+ }
+
+ public ExternalToolAction getExternalToolAction() {
+ return externalToolAction;
+ }
+
+ public void actionDialogOK() {
+ externalToolAction.setExternalToolName(runComposite.getLaunchConfigName());
+ }
+
+ public Composite createComposite(IBreakpointAction action, Composite composite, int style) {
+ externalToolAction = (ExternalToolAction) action;
+ runComposite = new ExternalToolActionComposite(composite, style, this);
+ return runComposite;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/GlobalActionsList.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/GlobalActionsList.java
new file mode 100644
index 00000000000..c80c66ac116
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/GlobalActionsList.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+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;
+
+public class GlobalActionsList extends Composite {
+
+ private Button attachButton = null;
+ private Button deleteButton = null;
+ private Button editButton = null;
+ private Button newButton = null;
+ private Table table = null;
+
+ public GlobalActionsList(Composite parent, int style, boolean useAttachButton) {
+ super(parent, style);
+ 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() {
+ public void widgetSelected(SelectionEvent e) {
+ updateButtons();
+ }
+
+ 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(Messages.getString("GlobalActionsList.0")); //$NON-NLS-1$
+
+ final TableColumn typeTableColumn = new TableColumn(table, SWT.NONE);
+ typeTableColumn.setWidth(120);
+ typeTableColumn.setText(Messages.getString("GlobalActionsList.1")); //$NON-NLS-1$
+
+ final TableColumn summaryTableColumn = new TableColumn(table, SWT.NONE);
+ summaryTableColumn.setWidth(120);
+ summaryTableColumn.setText(Messages.getString("GlobalActionsList.2")); //$NON-NLS-1$
+
+ ArrayList actions = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActions();
+ boolean hasActions = actions.size() > 0;
+
+ for (Iterator iter = CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActions().iterator(); iter.hasNext();) {
+ IBreakpointAction element = (IBreakpointAction) iter.next();
+ 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(Messages.getString("GlobalActionsList.3")); //$NON-NLS-1$
+ }
+
+ newButton = new Button(this, SWT.NONE);
+ newButton.setLayoutData(new GridData());
+ newButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+
+ try {
+ HandleNewButton();
+ } catch (CoreException e1) {
+ }
+ }
+ });
+ newButton.setText(Messages.getString("GlobalActionsList.4")); //$NON-NLS-1$
+ newButton.setEnabled(CDebugCorePlugin.getDefault().getBreakpointActionManager().getBreakpointActionExtensions().length > 0);
+
+ editButton = new Button(this, SWT.NONE);
+ editButton.setText(Messages.getString("GlobalActionsList.5")); //$NON-NLS-1$
+ editButton.addSelectionListener(new SelectionAdapter() {
+ 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.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ HandleDeleteButton();
+ }
+ });
+ deleteButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+ deleteButton.setText(Messages.getString("GlobalActionsList.6")); //$NON-NLS-1$
+ deleteButton.setEnabled(hasActions);
+ //
+ }
+
+ public Button getAttachButton() {
+ return attachButton;
+ }
+
+ public IBreakpointAction[] getSelectedActions() {
+ TableItem[] selectedItems = table.getSelection();
+ IBreakpointAction[] actionList = new IBreakpointAction[selectedItems.length];
+ int actionCount = 0;
+ for (int i = 0; i < selectedItems.length; i++) {
+ actionList[actionCount++] = (IBreakpointAction) selectedItems[i].getData();
+ }
+ return actionList;
+ }
+
+ protected void HandleDeleteButton() {
+ TableItem[] selectedItems = table.getSelection();
+ for (int i = 0; i < selectedItems.length; i++) {
+ IBreakpointAction action = (IBreakpointAction) selectedItems[i].getData();
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().deleteAction(action);
+ }
+ table.remove(table.getSelectionIndices());
+ if (table.getItemCount() > 0) {
+ table.select(table.getItemCount() - 1);
+ }
+ updateButtons();
+ }
+
+ protected void HandleEditButton() {
+
+ TableItem[] selectedItems = table.getSelection();
+ IBreakpointAction action = (IBreakpointAction) selectedItems[0].getData();
+
+ ActionDialog dialog = new ActionDialog(this.getShell(), action);
+ 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 {
+
+ ActionDialog dialog = new ActionDialog(this.getShell(), null);
+ int result = dialog.open();
+ if (result == Window.OK) {
+ IBreakpointAction action = dialog.getBreakpointAction();
+ action.setName(dialog.getActionName());
+ CDebugCorePlugin.getDefault().getBreakpointActionManager().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 > 0);
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/IBreakpointActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/IBreakpointActionPage.java
new file mode 100644
index 00000000000..f89419a0a6b
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/IBreakpointActionPage.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ * THIS INTERFACE IS PROVISIONAL AND WILL CHANGE IN THE FUTURE
+ * PLUG-INS USING THIS INTERFACE WILL NEED
+ * TO BE REVISED TO WORK WITH FUTURE VERSIONS OF CDT.
+ *
+ */
+
+public interface IBreakpointActionPage {
+
+ public void actionDialogCanceled();
+
+ public void actionDialogOK();
+
+ public Composite createComposite(IBreakpointAction action, Composite composite, int style);
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogAction.java
new file mode 100644
index 00000000000..b35aa49eee5
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogAction.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+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.eclipse.cdt.debug.core.breakpointactions.AbstractBreakpointAction;
+import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class LogAction extends AbstractBreakpointAction {
+
+ private String message = ""; //$NON-NLS-1$
+ private boolean evaluateExpression;
+ private MessageConsole console;
+
+ public boolean isEvaluateExpression() {
+ return evaluateExpression;
+ }
+
+ public void setEvaluateExpression(boolean evaluateExpression) {
+ this.evaluateExpression = evaluateExpression;
+ }
+
+ public void execute(IBreakpoint breakpoint, IAdaptable context) {
+ try {
+ openConsole(Messages.getString("LogAction.ConsoleTitle")); //$NON-NLS-1$
+ String logMessage = getMessage();
+
+ if (isEvaluateExpression()) {
+ ILogActionEnabler enabler = (ILogActionEnabler) context.getAdapter(ILogActionEnabler.class);
+ if (enabler != null)
+ logMessage = enabler.evaluateExpression(logMessage);
+ }
+
+ MessageConsoleStream stream = console.newMessageStream();
+ stream.println(logMessage);
+ stream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void openConsole(String consoleName) {
+ // add it if necessary
+ boolean found = false;
+
+ IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles();
+ for (int i = 0; i < consoles.length; i++) {
+ if (consoleName.equals(consoles[i].getName())) {
+ console = (MessageConsole) consoles[i];
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ console = new MessageConsole(consoleName, null);
+ ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
+ }
+
+ ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console);
+ }
+
+ public String getDefaultName() {
+ return Messages.getString("LogAction.UntitledName"); //$NON-NLS-1$
+ }
+
+ public String getIdentifier() {
+ return "org.eclipse.cdt.debug.ui.breakpointactions.LogAction"; //$NON-NLS-1$
+ }
+
+ public String getMemento() {
+ String logData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("logData"); //$NON-NLS-1$
+ rootElement.setAttribute("message", message); //$NON-NLS-1$
+ rootElement.setAttribute("evalExpr", Boolean.toString(evaluateExpression)); //$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);
+
+ logData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return logData;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getSummary() {
+ String summary = getMessage();
+ if (summary.length() > 32)
+ summary = getMessage().substring(0, 32);
+ return summary;
+ }
+
+ public String getTypeName() {
+ return Messages.getString("LogAction.TypeName"); //$NON-NLS-1$
+ }
+
+ 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();
+ String value = root.getAttribute("message"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ message = value;
+ value = root.getAttribute("evalExpr"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ evaluateExpression = Boolean.valueOf(value).booleanValue();
+ value = root.getAttribute("resume"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionComposite.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionComposite.java
new file mode 100644
index 00000000000..b2a76f84d9e
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionComposite.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+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.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class LogActionComposite extends Composite {
+
+ private Button expressionButton;
+ private LogActionPage logActionPage;
+ private Text message;
+
+ public LogActionComposite(Composite parent, int style, LogActionPage logActionPage) {
+ super(parent, style);
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ setLayout(gridLayout);
+
+ this.logActionPage = logActionPage;
+
+ final Label messageToLogLabel = new Label(this, SWT.NONE);
+ messageToLogLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false, 2, 1));
+ messageToLogLabel.setText(Messages.getString("LogActionComposite.0")); //$NON-NLS-1$
+
+ message = new Text(this, SWT.BORDER | SWT.WRAP);
+ message.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
+
+ expressionButton = new Button(this, SWT.CHECK);
+ expressionButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent e) {
+ }
+ });
+ expressionButton.setText(Messages.getString("LogActionComposite.1")); //$NON-NLS-1$
+ //
+
+ message.setText(this.logActionPage.getLogAction().getMessage());
+ expressionButton.setSelection(this.logActionPage.getLogAction().isEvaluateExpression());
+ }
+
+ protected void checkSubclass() {
+ // Disable the check that prevents subclassing of SWT components
+ }
+
+ public void dispose() {
+ super.dispose();
+ }
+
+ public boolean getIsExpression() {
+ return expressionButton.getSelection();
+ }
+
+ public String getMessage() {
+ return message.getText();
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionPage.java
new file mode 100644
index 00000000000..d6ed1b1eeae
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionPage.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.swt.widgets.Composite;
+
+public class LogActionPage extends PlatformObject implements IBreakpointActionPage {
+
+ private LogAction logAction;
+ private LogActionComposite editor;
+
+ public LogAction getLogAction() {
+ return logAction;
+ }
+
+ public void actionDialogCanceled() {
+ }
+
+ public void actionDialogOK() {
+ logAction.setMessage(editor.getMessage());
+ logAction.setEvaluateExpression(editor.getIsExpression());
+ }
+
+ public Composite createComposite(IBreakpointAction action, Composite composite, int style) {
+ logAction = (LogAction) action;
+ editor = new LogActionComposite(composite, style, this);
+ return editor;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/Messages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/Messages.java
new file mode 100644
index 00000000000..13dc00cafd6
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/Messages.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.ui.breakpointactions.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ // TODO Auto-generated method stub
+ 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/ui/breakpointactions/PreferenceConstants.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceConstants.java
new file mode 100644
index 00000000000..96a77c8e18f
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceConstants.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class PreferenceConstants {
+
+ public static final String P_PATH = "pathPreference"; //$NON-NLS-1$
+
+ public static final String P_BOOLEAN = "booleanPreference"; //$NON-NLS-1$
+
+ public static final String P_CHOICE = "choicePreference"; //$NON-NLS-1$
+
+ public static final String P_STRING = "stringPreference"; //$NON-NLS-1$
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceInitializer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceInitializer.java
new file mode 100644
index 00000000000..dd03f3a9c04
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceInitializer.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = CDebugUIPlugin.getDefault().getPreferenceStore();
+ store.setDefault(PreferenceConstants.P_BOOLEAN, true);
+ store.setDefault(PreferenceConstants.P_CHOICE, "choice2"); //$NON-NLS-1$
+ store.setDefault(PreferenceConstants.P_STRING, Messages.getString("PreferenceInitializer.1")); //$NON-NLS-1$
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeAction.java
new file mode 100644
index 00000000000..bb2f7c02316
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeAction.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+import java.text.MessageFormat;
+
+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.debug.core.breakpointactions.AbstractBreakpointAction;
+import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class ResumeAction extends AbstractBreakpointAction {
+
+ int pauseTime = 0;
+
+ public void execute(IBreakpoint breakpoint, IAdaptable context) {
+ IResumeActionEnabler enabler = (IResumeActionEnabler) context.getAdapter(IResumeActionEnabler.class);
+ if (enabler != null)
+ try {
+ enabler.resume();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getDefaultName() {
+ return Messages.getString("ResumeAction.UntitledName"); //$NON-NLS-1$
+ }
+
+ public int getPauseTime() {
+ return pauseTime;
+ }
+
+ public void setPauseTime(int pauseTime) {
+ this.pauseTime = pauseTime;
+ }
+
+ public String getIdentifier() {
+ return "org.eclipse.cdt.debug.ui.breakpointactions.ResumeAction"; //$NON-NLS-1$
+ }
+
+ public String getMemento() {
+ String resumeData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("resumeData"); //$NON-NLS-1$
+ rootElement.setAttribute("pauseTime", Integer.toString(pauseTime)); //$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);
+
+ resumeData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return resumeData;
+ }
+
+ public String getSummary() {
+ if (pauseTime == 0)
+ return Messages.getString("ResumeAction.SummaryImmediately"); //$NON-NLS-1$
+ return MessageFormat.format(Messages.getString("ResumeAction.SummaryResumeTime"), new Object[] { new Integer(pauseTime) }); //$NON-NLS-1$
+ }
+
+ public String getTypeName() {
+ return Messages.getString("ResumeAction.TypeName"); //$NON-NLS-1$
+ }
+
+ 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();
+ String value = root.getAttribute("pauseTime"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ pauseTime = Integer.parseInt(value);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionComposite.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionComposite.java
new file mode 100644
index 00000000000..9a1a9a9913b
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionComposite.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+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.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class ResumeActionComposite extends Composite {
+
+ private Text pauseTime;
+
+ /**
+ * Create the composite
+ *
+ * @param parent
+ * @param style
+ */
+ public ResumeActionComposite(Composite parent, int style, ResumeActionPage page) {
+ super(parent, style);
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 3;
+ setLayout(gridLayout);
+
+ final Label resumeAfterLabel = new Label(this, SWT.NONE);
+ resumeAfterLabel.setText(Messages.getString("ResumeActionComposite.ResumeAfterLabel")); //$NON-NLS-1$
+
+ pauseTime = new Text(this, SWT.BORDER);
+ pauseTime.setText(Integer.toString(page.getResumeAction().getPauseTime()));
+
+
+ final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ gridData.widthHint = 35;
+ pauseTime.setLayoutData(gridData);
+
+ final Label secondsLabel = new Label(this, SWT.NONE);
+ secondsLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ secondsLabel.setText(Messages.getString("ResumeActionComposite.Seconds")); //$NON-NLS-1$
+ //
+ }
+
+ public void dispose() {
+ super.dispose();
+ }
+
+ protected void checkSubclass() {
+ // Disable the check that prevents subclassing of SWT components
+ }
+
+ int getPauseTime() {
+ return Integer.parseInt(pauseTime.getText());
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionPage.java
new file mode 100644
index 00000000000..ebb8f578a92
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionPage.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.swt.widgets.Composite;
+
+public class ResumeActionPage extends PlatformObject implements IBreakpointActionPage {
+
+ private ResumeActionComposite resumeComposite;
+ private ResumeAction resumeAction;
+
+ public ResumeAction getResumeAction() {
+ return resumeAction;
+ }
+
+ public void actionDialogCanceled() {
+ }
+
+ public void actionDialogOK() {
+ resumeAction.setPauseTime(resumeComposite.getPauseTime());
+ }
+
+ public Composite createComposite(IBreakpointAction action, Composite composite, int style) {
+ resumeAction = (ResumeAction) action;
+ resumeComposite = new ResumeActionComposite(composite, style, this);
+ return resumeComposite;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundAction.java
new file mode 100644
index 00000000000..c795d93dab7
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundAction.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.UnsupportedAudioFileException;
+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.debug.core.breakpointactions.AbstractBreakpointAction;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class SoundAction extends AbstractBreakpointAction {
+
+ static public void playSoundFile(final File soundFile) {
+
+ class SoundPlayer extends Thread {
+
+ public void run() {
+ AudioInputStream soundStream;
+ try {
+ soundStream = AudioSystem.getAudioInputStream(soundFile);
+ AudioFormat audioFormat = soundStream.getFormat();
+ DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
+ SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
+ byte[] soundBuffer = new byte[5000];
+ sourceDataLine.open(audioFormat);
+ sourceDataLine.start();
+ int dataCount = 0;
+
+ while ((dataCount = soundStream.read(soundBuffer, 0, soundBuffer.length)) != -1) {
+ if (dataCount > 0) {
+ sourceDataLine.write(soundBuffer, 0, dataCount);
+ }
+ }
+ sourceDataLine.drain();
+ sourceDataLine.close();
+
+ } catch (UnsupportedAudioFileException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (LineUnavailableException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ }
+ ;
+
+ if (soundFile.exists()) {
+
+ new SoundPlayer().start();
+ }
+ }
+
+ private File soundFile;
+
+ public SoundAction() {
+ }
+
+ public void execute(IBreakpoint breakpoint, IAdaptable context) {
+ playSoundFile(soundFile);
+ }
+
+ public String getDefaultName() {
+ // if (soundFile != null) {
+ // return MessageFormat.format("Play {0}", new Object[]
+ // {soundFile.getName()});
+ // }
+ return "Untitled Sound Action"; //$NON-NLS-1$
+ }
+
+ public File getSoundFile() {
+ return soundFile;
+ }
+
+ public String getSummary() {
+ if (soundFile == null)
+ return new String(""); //$NON-NLS-1$
+ return soundFile.getAbsolutePath();
+ }
+
+ public String getTypeName() {
+ return Messages.getString("SoundAction.ActionTypeName"); //$NON-NLS-1$
+ }
+
+ public String getMemento() {
+ String soundData = new String(""); //$NON-NLS-1$
+ if (soundFile != null) {
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("soundData"); //$NON-NLS-1$
+ rootElement.setAttribute("file", soundFile.getAbsolutePath()); //$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);
+
+ soundData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return soundData;
+ }
+
+ 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();
+ String value = root.getAttribute("file"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+ soundFile = new File(value);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getIdentifier() {
+ return "org.eclipse.cdt.debug.ui.breakpointactions.SoundAction"; //$NON-NLS-1$
+ }
+
+ public void setSoundFile(File soundFile) {
+ this.soundFile = soundFile;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionComposite.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionComposite.java
new file mode 100644
index 00000000000..9792bddbbb2
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionComposite.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.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.FileDialog;
+import org.eclipse.swt.widgets.Label;
+
+public class SoundActionComposite extends Composite {
+
+ private static final String[] soundFileExtensions = new String[] { "*.wav", "*.mid", "*.au", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "*.aiff" }; //$NON-NLS-1$
+
+ private Combo combo_1;
+ private ModifyListener comboModifyListener = null;
+ private File selectedSoundFile = null;
+ private SoundActionPage soundActionPage;
+ private Label soundFilePathLabel;
+ private Button tryItButton;
+
+ /**
+ * Create the composite
+ *
+ * @param parent
+ * @param style
+ * @param page
+ */
+ public SoundActionComposite(Composite parent, int style, SoundActionPage page) {
+ super(parent, style);
+ soundActionPage = page;
+ final GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 2;
+ setLayout(gridLayout);
+
+ final Label playSoundLabel = new Label(this, SWT.NONE);
+ playSoundLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+ playSoundLabel.setText(Messages.getString("SoundActionComposite.4")); //$NON-NLS-1$
+
+ combo_1 = new Combo(this, SWT.READ_ONLY);
+ final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ combo_1.setLayoutData(gridData);
+
+ comboModifyListener = new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ if (combo_1.getText().length() > 0) {
+ setSoundFile(combo_1.getText());
+ }
+ }
+ };
+ rebuildRecentSoundsCombo();
+ combo_1.addModifyListener(comboModifyListener);
+
+ final String mediaPath = page.getMediaPath();
+
+ final Button browseButton = new Button(this, SWT.NONE);
+ browseButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(getShell(), SWT.NONE);
+ dialog.setText(Messages.getString("SoundActionComposite.5")); //$NON-NLS-1$
+ dialog.setFilterExtensions(soundFileExtensions);
+ if (mediaPath.length() > 0)
+ dialog.setFilterPath(mediaPath);
+
+ String res = dialog.open();
+ if (res != null) {
+ setSoundFile(res);
+ }
+ }
+ });
+ browseButton.setText(Messages.getString("SoundActionComposite.6")); //$NON-NLS-1$
+
+ tryItButton = new Button(this, SWT.NONE);
+ tryItButton.setLayoutData(new GridData());
+ tryItButton.setText(Messages.getString("SoundActionComposite.7")); //$NON-NLS-1$
+ tryItButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ File soundFile = new File(soundFilePathLabel.getText());
+ playSoundFile(soundFile);
+ }
+ });
+
+ soundFilePathLabel = new Label(this, SWT.NONE);
+ final GridData gridData_1 = new GridData(GridData.FILL_HORIZONTAL);
+ gridData_1.horizontalSpan = 2;
+ soundFilePathLabel.setLayoutData(gridData_1);
+ soundFilePathLabel.setText(""); //$NON-NLS-1$
+
+ //
+ if (soundActionPage.getSoundAction().getSoundFile() != null)
+ setSoundFile(soundActionPage.getSoundAction().getSoundFile().getAbsolutePath());
+ }
+
+ private void addRecentSound(File soundFile) {
+ soundActionPage.addRecentSound(soundFile);
+ rebuildRecentSoundsCombo();
+ }
+
+ protected void checkSubclass() {
+ // Disable the check that prevents subclassing of SWT components
+ }
+
+ public void dispose() {
+ super.dispose();
+ }
+
+ public File getSoundFile() {
+ return selectedSoundFile;
+ }
+
+ protected void playSoundFile(File soundFile) {
+ SoundAction.playSoundFile(soundFile);
+ }
+
+ private void rebuildRecentSoundsCombo() {
+ combo_1.removeAll();
+
+ ArrayList sortedSounds = new ArrayList(soundActionPage.getRecentSounds());
+ Collections.sort(sortedSounds);
+
+ for (Iterator iter = sortedSounds.iterator(); iter.hasNext();) {
+ File element = (File) iter.next();
+ combo_1.add(element.getAbsolutePath());
+ }
+ }
+
+ private void setSoundFile(String filePath) {
+ combo_1.removeModifyListener(comboModifyListener);
+ File soundFile = new File(filePath);
+ if (soundFile.exists()) {
+ addRecentSound(soundFile);
+ combo_1.setText(soundFile.getAbsolutePath());
+ soundFilePathLabel.setText(filePath);
+ tryItButton.setEnabled(true);
+ selectedSoundFile = soundFile;
+ } else {
+ soundFilePathLabel.setText(Messages.getString("SoundActionComposite.9")); //$NON-NLS-1$
+ tryItButton.setEnabled(false);
+ }
+ combo_1.addModifyListener(comboModifyListener);
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionPage.java
new file mode 100644
index 00000000000..1a36db45c44
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionPage.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * 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.debug.ui.breakpointactions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+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.debug.core.breakpointactions.IBreakpointAction;
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.swt.widgets.Composite;
+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;
+
+public class SoundActionPage extends PlatformObject implements IBreakpointActionPage {
+
+ private static final String SOUND_ACTION_RECENT = "SoundBehaviorDialog.recentSounds"; //$NON-NLS-1$
+
+ private static boolean isWindows() {
+ String os = System.getProperty("os.name"); //$NON-NLS-1$
+ return (os != null && os.toLowerCase().startsWith("win")); //$NON-NLS-1$
+ }
+
+ private static boolean isMacOS() {
+ String os = System.getProperty("os.name"); //$NON-NLS-1$
+ return (os != null && os.toLowerCase().startsWith("mac")); //$NON-NLS-1$
+ }
+
+ private SoundActionComposite editor = null;
+ private String mediaPath = ""; //$NON-NLS-1$
+
+ private ArrayList recentSounds = new ArrayList();
+
+ private SoundAction soundAction;
+
+ public SoundActionPage() {
+ if (isWindows())
+ mediaPath = "C:\\WINNT\\Media\\"; //$NON-NLS-1$
+ if (isMacOS())
+ mediaPath = "/System/Library/Sounds"; //$NON-NLS-1$
+
+ loadRecentSounds();
+ }
+
+ public void actionDialogCanceled() {
+ }
+
+ public void actionDialogOK() {
+ saveRecentSounds();
+ soundAction.setSoundFile(editor.getSoundFile());
+ }
+
+ public void addRecentSound(File soundFile) {
+ String soundFilePath = soundFile.getAbsolutePath();
+ int removeIndex = -1;
+ int fileCount = 0;
+ for (Iterator iter = recentSounds.iterator(); iter.hasNext() && removeIndex < 0;) {
+ File element = (File) iter.next();
+ if (element.getAbsolutePath().equals(soundFilePath))
+ removeIndex = fileCount;
+ fileCount++;
+ }
+ if (removeIndex >= 0)
+ recentSounds.remove(removeIndex);
+ recentSounds.add(soundFile);
+ if (recentSounds.size() > 10)
+ recentSounds.remove(0);
+
+ }
+
+ public Composite createComposite(IBreakpointAction action, Composite composite, int style) {
+ this.soundAction = (SoundAction) action;
+ loadRecentSounds();
+ if (soundAction.getSoundFile() == null && recentSounds.size() > 0)
+ soundAction.setSoundFile((File) recentSounds.get(0));
+ editor = new SoundActionComposite(composite, style, this);
+ return editor;
+ }
+
+ public String getMediaPath() {
+ return mediaPath;
+ }
+
+ public ArrayList getRecentSounds() {
+ return recentSounds;
+ }
+
+ public String getSummary() {
+ if (soundAction.getSoundFile() == null)
+ return new String(""); //$NON-NLS-1$
+ return soundAction.getSoundFile().getAbsolutePath();
+ }
+
+ private void initializeRecentSounds() {
+
+ if (isWindows()) {
+ String defaultSounds[] = { "chimes.wav", "chord.wav", "ding.wav", "notify.wav", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ "tada.wav" }; //$NON-NLS-1$
+
+ for (int i = 0; i < defaultSounds.length; i++) {
+ File soundFile = new File(mediaPath + defaultSounds[i]);
+ if (soundFile.exists())
+ recentSounds.add(soundFile);
+ }
+ }
+ if (isMacOS()) {
+ File macSounds = new File(mediaPath);
+ File[] soundFiles = macSounds.listFiles();
+
+ for (int i = 0; i < soundFiles.length; i++) {
+ String fileExtension = new Path(soundFiles[i].getAbsolutePath()).getFileExtension();
+ if (fileExtension.equalsIgnoreCase("aiff") || fileExtension.equalsIgnoreCase("wav")) //$NON-NLS-1$ //$NON-NLS-2$
+ recentSounds.add(soundFiles[i]);
+
+ }
+ }
+ saveRecentSounds();
+
+ }
+
+ private void loadRecentSounds() {
+ String recentSoundData = CDebugUIPlugin.getDefault().getPreferenceStore().getString(SOUND_ACTION_RECENT);
+
+ if (recentSoundData == null || recentSoundData.length() == 0) {
+ initializeRecentSounds();
+ return;
+ }
+
+ recentSounds = new ArrayList();
+
+ Element root = null;
+ DocumentBuilder parser;
+ try {
+ parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ parser.setErrorHandler(new DefaultHandler());
+ root = parser.parse(new InputSource(new StringReader(recentSoundData))).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("soundFileName")) { //$NON-NLS-1$
+ String value = subElement.getAttribute("name"); //$NON-NLS-1$
+ if (value == null)
+ throw new Exception();
+
+ File soundFile = new File(value);
+ if (soundFile.exists()) {
+ recentSounds.add(soundFile);
+ }
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (recentSounds.size() == 0)
+ initializeRecentSounds();
+ }
+
+ public void saveRecentSounds() {
+ String recentSoundData = new String(""); //$NON-NLS-1$
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = null;
+ try {
+ docBuilder = dfactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Element rootElement = doc.createElement("recentSounds"); //$NON-NLS-1$
+ doc.appendChild(rootElement);
+
+ for (Iterator iter = recentSounds.iterator(); iter.hasNext();) {
+ File soundFile = (File) iter.next();
+
+ Element element = doc.createElement("soundFileName"); //$NON-NLS-1$
+ element.setAttribute("name", soundFile.getAbsolutePath()); //$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);
+
+ recentSoundData = s.toString("UTF8"); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ CDebugUIPlugin.getDefault().getPreferenceStore().setValue(SOUND_ACTION_RECENT, recentSoundData);
+ }
+
+ public SoundAction getSoundAction() {
+ return soundAction;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties
new file mode 100644
index 00000000000..bcb8fe4a622
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties
@@ -0,0 +1,45 @@
+ActionsPropertyPage.1=Actions for this breakpoint:
+ActionsPropertyPage.2=Available actions:
+ActionsPreferencePage.0=Actions available for any breakpoint in the workspace:
+PreferenceInitializer.1=Default value
+GlobalActionsList.0=Name
+GlobalActionsList.1=Type
+GlobalActionsList.2=Summary
+GlobalActionsList.3=Attach
+GlobalActionsList.4=New...
+GlobalActionsList.5=Edit...
+GlobalActionsList.6=Delete
+ActionsList.0=Name
+ActionsList.1=Type
+ActionsList.2=Summary
+ActionsList.3=Remove
+ActionsList.4=Up
+ActionsList.5=Down
+ActionDialog.0=New Breakpoint Action
+ActionDialog.1=Action name:
+ActionDialog.2=Action type:
+SoundActionComposite.4=Select a sound to play when the breakpoint is hit:
+SoundActionComposite.5=Choose a sound file:
+SoundActionComposite.6=Browse...
+SoundActionComposite.7=Play Sound
+SoundActionComposite.9=That sound file does not exist.
+SoundAction.ActionTypeName=Sound Action
+LogActionComposite.0=Message to log when the breakpoint is hit:
+LogActionComposite.1=Evaluate as expression
+LogAction.ConsoleTitle=Log Action Messages
+LogAction.UntitledName=Untitled Log Action
+LogAction.TypeName=Log Action
+
+ExternalToolActionComposite.ToolLabel=External Tool:
+ExternalToolActionComposite.DialogTitle=External Tools
+ExternalToolActionComposite.DialogMessage=Choose an External Tool to run
+ExternalToolActionComposite.ChooseButtonTitle=Choose...
+ExternalToolActionComposite.ExternalToolsButtonTitle=External Tools...
+ExternalToolAction.Summary=Run {0}
+ExternalToolAction.TypeName=External Tool Action
+ResumeAction.UntitledName=Untitled Resume Action
+ResumeAction.SummaryImmediately=Resume immediately
+ResumeActionComposite.ResumeAfterLabel=Resume after
+ResumeAction.SummaryResumeTime=Resume after {0} seconds
+ResumeActionComposite.Seconds=seconds
+ResumeAction.TypeName=Resume Action