From 02af47ffb61180e98add9018ab5f4fa1c846b467 Mon Sep 17 00:00:00 2001 From: Ken Ryall Date: Wed, 28 Mar 2007 23:29:04 +0000 Subject: [PATCH] Bug 118308 support for breakpoint actions. --- .../META-INF/MANIFEST.MF | 1 + .../plugin.properties | 6 +- debug/org.eclipse.cdt.debug.core/plugin.xml | 16 + .../schema/BreakpointAction.exsd | 106 +++++++ .../cdt/debug/core/CDebugCorePlugin.java | 21 +- .../AbstractBreakpointAction.java | 27 ++ .../BreakpointActionAdapterFactory.java | 36 +++ .../BreakpointActionManager.java | 238 +++++++++++++++ .../breakpointactions/IBreakpointAction.java | 44 +++ .../breakpointactions/ILogActionEnabler.java | 24 ++ .../IResumeActionEnabler.java | 25 ++ .../breakpointactions/LogActionEnabler.java | 33 +++ .../ResumeActionEnabler.java | 27 ++ .../debug/internal/core/model/CThread.java | 19 +- .../plugin.properties | 8 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 105 ++++++- .../schema/BreakpointActionPage.exsd | 103 +++++++ .../ui/breakpointactions/ActionDialog.java | 276 ++++++++++++++++++ .../ui/breakpointactions/ActionsList.java | 183 ++++++++++++ .../ActionsPreferencePage.java | 64 ++++ .../ActionsPropertyPage.java | 126 ++++++++ .../breakpointactions/ExternalToolAction.java | 130 +++++++++ .../ExternalToolActionComposite.java | 238 +++++++++++++++ .../ExternalToolActionPage.java | 39 +++ .../breakpointactions/GlobalActionsList.java | 200 +++++++++++++ .../IBreakpointActionPage.java | 32 ++ .../debug/ui/breakpointactions/LogAction.java | 178 +++++++++++ .../breakpointactions/LogActionComposite.java | 72 +++++ .../ui/breakpointactions/LogActionPage.java | 40 +++ .../debug/ui/breakpointactions/Messages.java | 32 ++ .../PreferenceConstants.java | 26 ++ .../PreferenceInitializer.java | 34 +++ .../ui/breakpointactions/ResumeAction.java | 123 ++++++++ .../ResumeActionComposite.java | 65 +++++ .../breakpointactions/ResumeActionPage.java | 39 +++ .../ui/breakpointactions/SoundAction.java | 178 +++++++++++ .../SoundActionComposite.java | 164 +++++++++++ .../ui/breakpointactions/SoundActionPage.java | 237 +++++++++++++++ .../ui/breakpointactions/messages.properties | 45 +++ 39 files changed, 3348 insertions(+), 12 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/schema/BreakpointAction.exsd create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/AbstractBreakpointAction.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionAdapterFactory.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/BreakpointActionManager.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IBreakpointAction.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ILogActionEnabler.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IResumeActionEnabler.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/LogActionEnabler.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ResumeActionEnabler.java create mode 100644 debug/org.eclipse.cdt.debug.ui/schema/BreakpointActionPage.exsd create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionDialog.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsList.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPreferencePage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ActionsPropertyPage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolAction.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionComposite.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ExternalToolActionPage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/GlobalActionsList.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/IBreakpointActionPage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogAction.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionComposite.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/LogActionPage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/Messages.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceConstants.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/PreferenceInitializer.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeAction.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionComposite.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/ResumeActionPage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundAction.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionComposite.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/SoundActionPage.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties 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