diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java index 617f64e2583..924c5b65214 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/ConsolePageParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Marc-Andre Laperle and others. + * Copyright (c) 2010, 2011 Marc-Andre Laperle 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 @@ -10,25 +10,52 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.console; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants; import org.eclipse.cdt.dsf.gdb.launching.GDBProcess; +import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess; +import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleConstants; import org.eclipse.ui.console.IConsolePageParticipant; +import org.eclipse.ui.console.IConsoleView; import org.eclipse.ui.console.TextConsole; import org.eclipse.ui.part.IPageBookViewPage; /** - * A console page participant for both the gdb tracing console and the gdb CLI console + * A console page participant for DSF-GDB. + * It adds a save button to both the gdb tracing console and the gdb CLI console. + * It also brings to the front the proper inferior console when a container is selected. * * @since 2.1 */ -public class ConsolePageParticipant implements IConsolePageParticipant{ +public class ConsolePageParticipant implements IConsolePageParticipant, IDebugContextListener { + private IConsole fConsole; + private IPageBookViewPage fPage; + private IConsoleView fView; + public void init(IPageBookViewPage page, IConsole console) { - if(console instanceof TracingConsole || isConsoleGdbCli(console)) - { + fPage = page; + fConsole = console; + fView = (IConsoleView)fPage.getSite().getPage().findView(IConsoleConstants.ID_CONSOLE_VIEW); + + if (isConsoleInferior(console) || isConsoleGdbCli(console)) { + // This console participant will affect all consoles, even those not for DSF-GDB. + // Only consoles for GDBProcess or InferiorRuntimeProcess are what we care about for DSF-GDB + DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).addDebugContextListener(this); + } + + if(console instanceof TracingConsole || isConsoleGdbCli(console)) { TextConsole textConsole = (TextConsole) console; // Add the save console action @@ -55,12 +82,30 @@ public class ConsolePageParticipant implements IConsolePageParticipant{ return false; } + /** + * Checks if the the console is for an inferior. + * + * @param console The console to check + * @return true if the the console is for an inferior + */ + private boolean isConsoleInferior(IConsole console) { + if(console instanceof org.eclipse.debug.ui.console.IConsole) { + org.eclipse.debug.ui.console.IConsole debugConsole = (org.eclipse.debug.ui.console.IConsole)console; + return (debugConsole.getProcess() instanceof InferiorRuntimeProcess); + } + return false; + } + @SuppressWarnings("rawtypes") public Object getAdapter(Class adapter) { return null; } public void dispose() { + if (isConsoleInferior(fConsole) || isConsoleGdbCli(fConsole)) { + DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).removeDebugContextListener(this); + } + fConsole = null; } public void activated() { @@ -69,4 +114,68 @@ public class ConsolePageParticipant implements IConsolePageParticipant{ public void deactivated() { } + protected IProcess getConsoleProcess() { + if (fConsole instanceof org.eclipse.debug.ui.console.IConsole) { + return ((org.eclipse.debug.ui.console.IConsole)fConsole).getProcess(); + } + return null; + } + + protected IProcess getCurrentProcess() { + IAdaptable context = DebugUITools.getDebugContext(); + + // If the launch is selected, we should choose the first inferior being debugged + if (context instanceof ILaunch) { + ILaunch launch = (ILaunch)context; + + IProcess[] processes = launch.getProcesses(); + if (processes != null && processes.length > 0) { + for (IProcess process : processes) { + if (process instanceof InferiorRuntimeProcess) { + return process; + } + } + + // No inferior? return the gdb process + // We have to check that the process is actually from a DSF-GDB session, + // since the current context could be for any debug session + if (processes[0] instanceof GDBProcess) { + return launch.getProcesses()[0]; + } + } + + return null; + } + + if (context != null) { + // Look for the process that this context refers to, so we can select its console + IDMContext dmc = (IDMContext)context.getAdapter(IDMContext.class); + IMIContainerDMContext container = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class); + if (container != null) { + ILaunch launch = (ILaunch)context.getAdapter(ILaunch.class); + if (launch != null) { + for (IProcess process : launch.getProcesses()) { + String groupId = process.getAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR); + if (container.getGroupId().equals(groupId)) { + return process; + } + } + } + } + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener#contextEvent(org.eclipse.debug.internal.ui.contexts.provisional.DebugContextEvent) + */ + public void debugContextChanged(DebugContextEvent event) { + if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { + IProcess consoleProcess = getConsoleProcess(); + if (fView != null && consoleProcess != null && consoleProcess.equals(getCurrentProcess())) { + fView.display(fConsole); + } + } + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java new file mode 100644 index 00000000000..c1ecd5ee0a9 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/IGdbDebugConstants.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2011 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - initial implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb; + +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; + + + +/** + * @noimplement This interface is not intended to be implemented by clients. + * @since 4.0 + */ +public interface IGdbDebugConstants { + + public static final String PREFIX = GdbPlugin.PLUGIN_ID + "."; //$NON-NLS-1$ + + /** + * Attribute key to be added to the IProcess associated with an IMIContainerDMContext. + * The value should be the groupId as returned by {@link IMIContainerDMContext#getGroupId()} + */ + public static final String INFERIOR_GROUPID_ATTR = PREFIX + "inferiorGroupId"; //$NON-NLS-1$ + + +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java index dc3e38d4892..91f2f88ee1e 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java @@ -52,7 +52,6 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IDisconnect; import org.eclipse.debug.core.model.IMemoryBlockRetrieval; -import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.ITerminate; @@ -171,18 +170,6 @@ public class GdbLaunch extends DsfLaunch GDBProcess gdbProcess = new GDBProcess(this, cliProc, label, null); addProcess(gdbProcess); - - Object existingAdapter = getSession().getModelAdapter(IProcess.class); - if (existingAdapter == null) { - // Register the model adapter to the gdbProcess only if there is no other one - // registered already; if there is already one, it is from our inferior process - // and it takes precedence because we want the inferior console to show - // when we select a debug context of this debug session. - // If the inferior process is added later, it will properly overwrite this model adapter. - // Note that we don't always have an inferior console, so it is important to register - // this adapter for those cases. - getSession().registerModelAdapter(IProcess.class, gdbProcess); - } } catch (InterruptedException e) { throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$ } catch (ExecutionException e) { diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/InferiorRuntimeProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/InferiorRuntimeProcess.java new file mode 100644 index 00000000000..0e05153678e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/InferiorRuntimeProcess.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2011 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.launching; + +import java.util.Map; + +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.RuntimeProcess; + +/** + * A process for the inferior to know it belongs to a DSF-GDB session + * + * @since 4.0 + */ +public class InferiorRuntimeProcess extends RuntimeProcess { + + public InferiorRuntimeProcess(ILaunch launch, Process process, String name, + Map attributes) { + super(launch, process, name, attributes); + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java index 1da779cdd9a..aad1cdbce91 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java @@ -34,9 +34,10 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent; import org.eclipse.cdt.dsf.debug.service.command.ICommand; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants; import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; -import org.eclipse.cdt.dsf.gdb.launching.GDBProcess; +import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.IMICommandControl; import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; @@ -463,7 +464,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses { IProcess[] launchProcesses = launch.getProcesses(); for (IProcess p : launchProcesses) { // We know there is only one inferior, so just find it. - if ((p instanceof GDBProcess) == false) { + if (p instanceof InferiorRuntimeProcess) { launch.removeProcess(p); break; } @@ -471,11 +472,10 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses { } // Add the inferior - IProcess process = DebugPlugin.newProcess(launch, inferior, label); + InferiorRuntimeProcess runtimeInferior = new InferiorRuntimeProcess(launch, inferior, label, null); + runtimeInferior.setAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR, MIProcesses.UNIQUE_GROUP_ID); + launch.addProcess(runtimeInferior); - // Register as an IProcess so that the console is brought to the front - // when the inferior is selected - getSession().registerModelAdapter(IProcess.class, process); rm.done(); } }); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java index b3c878316bd..dace4e14e23 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java @@ -26,7 +26,9 @@ import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContex import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommand; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.IMICommandControl; import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; @@ -53,9 +55,7 @@ import org.eclipse.debug.core.model.IProcess; * @since 4.0 */ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence { - - private static final String GROUP_ATTR = GdbPlugin.PLUGIN_ID + "groupId"; //$NON-NLS-1$ - + private IGDBControl fCommandControl; private CommandFactory fCommandFactory; private IGDBProcesses fProcService; @@ -290,7 +290,7 @@ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence { // For a restart, remove the old inferior IProcess[] launchProcesses = launch.getProcesses(); for (IProcess process : launchProcesses) { - String groupAttribute = process.getAttribute(GROUP_ATTR); + String groupAttribute = process.getAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR); if (groupId.equals(groupAttribute)) { launch.removeProcess(process); // Use the exact same label as before @@ -301,12 +301,10 @@ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence { } // Add the inferior - IProcess process = DebugPlugin.newProcess(launch, inferior, label); - process.setAttribute(GROUP_ATTR, groupId); - - // Register as an IProcess so that the console is brought to the front - // when the inferior is selected - session.registerModelAdapter(IProcess.class, process); + InferiorRuntimeProcess runtimeInferior = new InferiorRuntimeProcess(launch, inferior, label, null); + runtimeInferior.setAttribute(IGdbDebugConstants.INFERIOR_GROUPID_ATTR, groupId); + launch.addProcess(runtimeInferior); + rm.done(); } });