diff options
25 files changed, 1049 insertions, 82 deletions
diff --git a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF index 1959b198321..cb55d1ce0b7 100644 --- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.ui; singleton:=true -Bundle-Version: 8.0.0.qualifier +Bundle-Version: 8.1.0.qualifier Bundle-Activator: org.eclipse.cdt.debug.ui.CDebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -26,6 +26,7 @@ Export-Package: org.eclipse.cdt.debug.internal.ui.propertypages;x-internal:=true, org.eclipse.cdt.debug.internal.ui.sourcelookup;x-friends:="org.eclipse.cdt.dsf.ui", org.eclipse.cdt.debug.internal.ui.views;x-internal:=true, + org.eclipse.cdt.debug.internal.ui.views.debuggerconsole;x-internal:=true, org.eclipse.cdt.debug.internal.ui.views.executables;x-internal:=true, org.eclipse.cdt.debug.internal.ui.views.memory;x-internal:=true, org.eclipse.cdt.debug.internal.ui.views.modules;x-internal:=true, @@ -33,6 +34,7 @@ Export-Package: org.eclipse.cdt.debug.ui, org.eclipse.cdt.debug.ui.breakpointactions, org.eclipse.cdt.debug.ui.breakpoints, + org.eclipse.cdt.debug.ui.debuggerconsole, org.eclipse.cdt.debug.ui.disassembly, org.eclipse.cdt.debug.ui.disassembly.rulers, org.eclipse.cdt.debug.ui.editors, diff --git a/debug/org.eclipse.cdt.debug.ui/icons/obj16/debugger_console_select.gif b/debug/org.eclipse.cdt.debug.ui/icons/obj16/debugger_console_select.gif Binary files differnew file mode 100644 index 00000000000..a598f6082f6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/icons/obj16/debugger_console_select.gif diff --git a/debug/org.eclipse.cdt.debug.ui/icons/view16/debugger_console_view.png b/debug/org.eclipse.cdt.debug.ui/icons/view16/debugger_console_view.png Binary files differnew file mode 100644 index 00000000000..a060ac5b488 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/icons/view16/debugger_console_view.png diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index 01b1e40e46b..50578110b97 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -274,3 +274,6 @@ DebugNewExecutable.tooltip=Debug a new executable # Step into selection popup.stepIntoSelection.description=Step into the current selected statement popup.stepIntoSelection.name=Step Into Selection + +# Debugger console view +DebuggerConsoleView.name=Debugger Console diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index ee795660e37..db15cf4be29 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -175,6 +175,13 @@ class="org.eclipse.cdt.debug.internal.ui.views.signals.FlexibleSignalsView" id="org.eclipse.cdt.debug.ui.SignalsView"> </view> + <view + name="%DebuggerConsoleView.name" + icon="icons/view16/debugger_console_view.png" + category="org.eclipse.debug.ui" + class="org.eclipse.cdt.debug.internal.ui.views.debuggerconsole.DebuggerConsoleView" + id="org.eclipse.cdt.debug.ui.debuggerConsoleView"> + </view> </extension> <extension point="org.eclipse.ui.perspectiveExtensions"> diff --git a/debug/org.eclipse.cdt.debug.ui/pom.xml b/debug/org.eclipse.cdt.debug.ui/pom.xml index 1cc23af4a3e..a0d7e26d82d 100644 --- a/debug/org.eclipse.cdt.debug.ui/pom.xml +++ b/debug/org.eclipse.cdt.debug.ui/pom.xml @@ -11,7 +11,7 @@ <relativePath>../../pom.xml</relativePath> </parent> - <version>8.0.0-SNAPSHOT</version> + <version>8.1.0-SNAPSHOT</version> <artifactId>org.eclipse.cdt.debug.ui</artifactId> <packaging>eclipse-plugin</packaging> </project> diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java index 4a7dfaa06f6..a655d4ef78f 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java @@ -134,6 +134,8 @@ public class CDebugImages { public static final String IMG_WIZBAN_PATH_MAPPING = NAME_PREFIX + "mapping_wiz.gif"; //$NON-NLS-1$ public static final String IMG_WIZBAN_PATH_MAP_ENTRY = NAME_PREFIX + "mapentry_wiz.gif"; //$NON-NLS-1$ + public static final String IMG_DEBUGGER_CONSOLE_SELECT = NAME_PREFIX + "debugger_console_select.gif"; //$NON-NLS-1$ + /* * Set of predefined Image Descriptors. */ @@ -203,6 +205,7 @@ public class CDebugImages { public static final ImageDescriptor DESC_OBJS_PATH_MAP_ENTRY = createManaged(T_OBJ, IMG_OBJS_PATH_MAP_ENTRY); public static final ImageDescriptor DESC_OBJS_COMMON_TAB = createManaged(T_OBJ, IMG_OBJS_COMMON_TAB); public static final ImageDescriptor DESC_OBJS_ARRAY_PARTITION = createManaged(T_OBJ, IMG_OBJS_ARRAY_PARTITION); + public static final ImageDescriptor DESC_OBJS_DEBUGGER_CONSOLE_SELECT = createManaged(T_OBJ, IMG_DEBUGGER_CONSOLE_SELECT); public static final ImageDescriptor DESC_WIZBAN_ADD_SOURCE = createManaged(T_WIZBAN, IMG_WIZBAN_ADD_SOURCE); public static final ImageDescriptor DESC_WIZBAN_PATH_MAPPING = createManaged(T_WIZBAN, IMG_WIZBAN_PATH_MAPPING); public static final ImageDescriptor DESC_WIZBAN_PATH_MAP_ENTRY = createManaged(T_WIZBAN, IMG_WIZBAN_PATH_MAP_ENTRY); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/ConsoleMessages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/ConsoleMessages.java new file mode 100644 index 00000000000..b178d1cbca3 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/ConsoleMessages.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views.debuggerconsole; + +import org.eclipse.osgi.util.NLS; + +public class ConsoleMessages extends NLS { + public static String ConsoleMessages_no_console; + public static String ConsoleDropDownAction_name; + public static String ConsoleDropDownAction_description; + + static { + // initialize resource bundle + NLS.initializeMessages(ConsoleMessages.class.getName(), ConsoleMessages.class); + } + + private ConsoleMessages() { + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/ConsoleMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/ConsoleMessages.properties new file mode 100644 index 00000000000..919a0d4aabe --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/ConsoleMessages.properties @@ -0,0 +1,12 @@ +########################################################################## +# Copyright (c) 2016 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 +########################################################################## + +ConsoleMessages_no_console=No console to display at this time. + +ConsoleDropDownAction_name=Select Console +ConsoleDropDownAction_description=Display Selected Console diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleDropDownAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleDropDownAction.java new file mode 100644 index 00000000000..2811a3162dd --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleDropDownAction.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views.debuggerconsole; + +import org.eclipse.cdt.debug.internal.ui.CDebugImages; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleManager; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleListener; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * Drop down action in the DebuggerConsoleView to select which console to display. + */ +public class DebuggerConsoleDropDownAction extends Action implements IMenuCreator, IConsoleListener, IUpdate { + + private DebuggerConsoleView fView; + private Menu fMenu; + + public DebuggerConsoleDropDownAction(DebuggerConsoleView view) { + fView = view; + setText(ConsoleMessages.ConsoleDropDownAction_name); + setToolTipText(ConsoleMessages.ConsoleDropDownAction_description); + setImageDescriptor(CDebugImages.DESC_OBJS_DEBUGGER_CONSOLE_SELECT); + setMenuCreator(this); + getDebuggerConsoleManager().addConsoleListener(this); + update(); + } + + @Override + public void dispose() { + if (fMenu != null) { + fMenu.dispose(); + } + + fView = null; + getDebuggerConsoleManager().removeConsoleListener(this); + } + + private IDebuggerConsoleManager getDebuggerConsoleManager() { + return CDebugUIPlugin.getDebuggerConsoleManager(); + } + + @Override + public void update() { + IDebuggerConsole[] consoles = getDebuggerConsoleManager().getConsoles(); + // Keep the button enabled as soon as there is at least one console. + // Having it disabled for a single console can prove confusing to users, + // so we enable it even for a single console. + setEnabled(consoles.length > 0); + } + + @Override + public Menu getMenu(Menu parent) { + return null; + } + + @Override + public Menu getMenu(Control parent) { + if (fMenu != null) { + fMenu.dispose(); + } + + fMenu = new Menu(parent); + IDebuggerConsole[] consoles = getDebuggerConsoleManager().getConsoles(); + IDebuggerConsole current = fView.getCurrentConsole(); + for (int i = 0; i < consoles.length; i++) { + IDebuggerConsole console = consoles[i]; + Action action = new DebuggerShowConsoleAction(fView, console); + action.setChecked(console.equals(current)); + addActionToMenu(fMenu, action, i + 1); + } + return fMenu; + } + + private void addActionToMenu(Menu parent, Action action, int accelerator) { + if (accelerator < 10) { + StringBuffer label= new StringBuffer(); + //add the numerical accelerator + label.append('&'); + label.append(accelerator); + label.append(' '); + label.append(action.getText()); + action.setText(label.toString()); + } + ActionContributionItem item= new ActionContributionItem(action); + item.fill(parent, -1); + } + + @Override + public void run() { + IDebuggerConsole[] consoles = getDebuggerConsoleManager().getConsoles(); + IDebuggerConsole current = fView.getCurrentConsole(); + int idx = 0; + for (int i = 0; i < consoles.length; i++) { + idx = i; + if (consoles[i] == current) { + break; + } + } + int next = idx+1; + if (next >= consoles.length) { + next = 0; + } + fView.display(consoles[next]); + } + + @Override + public void consolesAdded(IConsole[] consoles) { + UIJob job = new UIJob("") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + update(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.setPriority(Job.INTERACTIVE); + job.schedule(); + } + + @Override + public void consolesRemoved(IConsole[] consoles) { + UIJob job = new UIJob("") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if (fMenu != null) { + fMenu.dispose(); + } + update(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.setPriority(Job.INTERACTIVE); + job.schedule(); + } +}
\ No newline at end of file diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleManager.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleManager.java new file mode 100644 index 00000000000..ca17bc087a2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleManager.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2009, 2015 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.debug.internal.ui.views.debuggerconsole; + +import java.util.ArrayList; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleManager; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleListener; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * A singleton Debugger Console manager which handles keeping track of all + * active debugger consoles. + */ +public class DebuggerConsoleManager implements IDebuggerConsoleManager { + + /** A list of all known consoles */ + private ArrayList<IDebuggerConsole> fConsoleList = new ArrayList<>(); + + /** A list of listeners registered for notifications of changes to consoles */ + private ListenerList<IConsoleListener> fConsoleListeners = new ListenerList<>(); + + private ShowDebuggerConsoleViewJob fShowDebuggerConsoleViewJob = new ShowDebuggerConsoleViewJob(); + + @Override + public void addConsoleListener(IConsoleListener listener) { + fConsoleListeners.add(listener); + } + + @Override + public void removeConsoleListener(IConsoleListener listener) { + fConsoleListeners.remove(listener); + } + + @Override + public IDebuggerConsole[] getConsoles() { + synchronized (fConsoleList) { + return fConsoleList.toArray(new IDebuggerConsole[fConsoleList.size()]); + } + } + + @Override + public void addConsole(IDebuggerConsole console) { + synchronized (fConsoleList) { + fConsoleList.add(console); + } + for (IConsoleListener listener : fConsoleListeners) { + listener.consolesAdded(new IConsole[] { console }); + } + } + + @Override + public void removeConsole(IDebuggerConsole console) { + synchronized (fConsoleList) { + fConsoleList.remove(console); + } + for (IConsoleListener listener : fConsoleListeners) { + listener.consolesRemoved(new IConsole[] { console }); + } + } + + @Override + public void showConsoleView(IDebuggerConsole console) { + fShowDebuggerConsoleViewJob.setConsole(console); + fShowDebuggerConsoleViewJob.schedule(100); + } + + private class ShowDebuggerConsoleViewJob extends WorkbenchJob { + private IConsole fConsole; + + ShowDebuggerConsoleViewJob() { + super("Show GDB Console View"); //$NON-NLS-1$ + setSystem(true); + setPriority(Job.SHORT); + } + + void setConsole(IConsole console) { + fConsole = console; + } + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null && fConsole != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + boolean consoleFound = false; + IViewPart view = page.findView(DebuggerConsoleView.DEBUGGER_CONSOLE_VIEW_ID); + if (view != null) { + DebuggerConsoleView consoleView = (DebuggerConsoleView)view; + boolean consoleVisible = page.isPartVisible(consoleView); + if (consoleVisible) { + consoleFound = true; + page.bringToTop(consoleView); + } + } + + if (!consoleFound) { + try { + DebuggerConsoleView consoleView = + (DebuggerConsoleView)page.showView(DebuggerConsoleView.DEBUGGER_CONSOLE_VIEW_ID, + null, + IWorkbenchPage.VIEW_CREATE); + page.bringToTop(consoleView); + } catch (PartInitException e) { + CDebugUIPlugin.log(e); + } + } + } + } + fConsole = null; + return Status.OK_STATUS; + } + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java new file mode 100644 index 00000000000..b35dc4ec98c --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java @@ -0,0 +1,310 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views.debuggerconsole; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleManager; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleView; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleListener; +import org.eclipse.ui.part.IPage; +import org.eclipse.ui.part.IPageBookViewPage; +import org.eclipse.ui.part.MessagePage; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.part.PageBookView; +import org.eclipse.ui.part.PageSwitcher; + +public class DebuggerConsoleView extends PageBookView implements IDebuggerConsoleView, IConsoleListener, IPropertyChangeListener { + + public static final String DEBUGGER_CONSOLE_VIEW_ID = "org.eclipse.cdt.debug.ui.debuggerConsoleView"; //$NON-NLS-1$ + + /** The console being displayed, or <code>null</code> if none */ + private IDebuggerConsole fActiveConsole; + + /** Map of consoles to dummy console parts (used to close pages) */ + private Map<IDebuggerConsole, DebuggerConsoleWorkbenchPart> fConsoleToPart = new HashMap<>(); + + /** Map of parts to consoles */ + private Map<DebuggerConsoleWorkbenchPart, IDebuggerConsole> fPartToConsole = new HashMap<>(); + + private DebuggerConsoleDropDownAction fDisplayConsoleAction; + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + createActions(); + configureToolBar(getViewSite().getActionBars().getToolBarManager()); + + // create pages for existing consoles + IConsole[] consoles = getConsoleManager().getConsoles(); + consolesAdded(consoles); + + // add as a listener for new consoles + getConsoleManager().addConsoleListener(this); + + getViewSite().getActionBars().updateActionBars(); + initPageSwitcher(); + } + + @Override + protected PageRec doCreatePage(IWorkbenchPart dummyPart) { + DebuggerConsoleWorkbenchPart part = (DebuggerConsoleWorkbenchPart)dummyPart; + IDebuggerConsole console = fPartToConsole.get(part); + IPageBookViewPage page = console.createPage(this); + initPage(page); + page.createControl(getPageBook()); + console.addPropertyChangeListener(this); + + return new PageRec(dummyPart, page); + } + + protected void createActions() { + fDisplayConsoleAction = new DebuggerConsoleDropDownAction(this); + } + + protected void configureToolBar(IToolBarManager mgr) { + mgr.add(fDisplayConsoleAction); + } + + @Override + public void dispose() { + super.dispose(); + getConsoleManager().removeConsoleListener(this); + + if (fDisplayConsoleAction != null) { + fDisplayConsoleAction.dispose(); + fDisplayConsoleAction = null; + } + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + // This is important to update the title of a console when it terminates + Object source = event.getSource(); + if (source instanceof IConsole && event.getProperty().equals(IBasicPropertyConstants.P_TEXT)) { + if (source.equals(getCurrentConsole())) { + updateTitle(); + } + } + + } + + private boolean isAvailable() { + return getPageBook() != null && !getPageBook().isDisposed(); + } + + /** + * Returns the currently displayed console. + */ + @Override + public IDebuggerConsole getCurrentConsole() { + return fActiveConsole; + } + + @Override + protected void showPageRec(PageRec pageRec) { + IDebuggerConsole recConsole = fPartToConsole.get(pageRec.part); + if (recConsole != null && recConsole.equals(getCurrentConsole())) { + return; + } + + super.showPageRec(pageRec); + fActiveConsole = recConsole; + + updateTitle(); + } + + /** + * Returns a set of consoles known by the view. + */ + protected Set<IDebuggerConsole> getConsoles() { + return fConsoleToPart.keySet(); + } + + /** + * Updates the view title based on the active console + */ + protected void updateTitle() { + IConsole console = getCurrentConsole(); + if (console == null) { + setContentDescription(ConsoleMessages.ConsoleMessages_no_console); + } else { + String newName = console.getName(); + String oldName = getContentDescription(); + if (newName != null && !newName.equals(oldName)) { + setContentDescription(newName); + } + } + } + + @Override + protected void doDestroyPage(IWorkbenchPart part, PageRec pageRecord) { + pageRecord.page.dispose(); + pageRecord.dispose(); + + IConsole console = fPartToConsole.remove(part); + fConsoleToPart.remove(console); + console.removePropertyChangeListener(this); + + if (fPartToConsole.isEmpty()) { + fActiveConsole = null; + } + } + + @Override + protected boolean isImportant(IWorkbenchPart part) { + return part instanceof DebuggerConsoleWorkbenchPart; + } + + private IDebuggerConsoleManager getConsoleManager() { + return CDebugUIPlugin.getDebuggerConsoleManager(); + } + + @Override + protected IPage createDefaultPage(PageBook book) { + MessagePage page = new MessagePage(); + page.createControl(getPageBook()); + initPage(page); + return page; + } + + @Override + public void consolesAdded(IConsole[] consoles) { + if (isAvailable()) { + asyncExec(() -> { + for (IConsole console : consoles) { + if (isAvailable()) { + // Ensure console is still registered since this is done asynchronously + IDebuggerConsole[] allConsoles = getConsoleManager().getConsoles(); + for (IDebuggerConsole registered : allConsoles) { + if (registered.equals(console)) { + DebuggerConsoleWorkbenchPart part = new DebuggerConsoleWorkbenchPart(registered, getSite()); + fConsoleToPart.put(registered, part); + fPartToConsole.put(part, registered); + partActivated(part); + break; + } + } + + } + } + }); + } + } + + @Override + public void consolesRemoved(IConsole[] consoles) { + if (isAvailable()) { + asyncExec(() -> { + for (IConsole console : consoles) { + if (isAvailable()) { + DebuggerConsoleWorkbenchPart part = fConsoleToPart.get(console); + if (part != null) { + // partClosed() will also cleanup our maps + partClosed(part); + } + if (getCurrentConsole() == null) { + // When a part is closed, the page that is shown becomes + // the default page, which does not have a console. + // We want to select a page with a console instead. + IDebuggerConsole[] available = getConsoleManager().getConsoles(); + if (available.length > 0) { + display(available[available.length - 1]); + } + } + } + } + }); + } + } + + @Override + public void display(IDebuggerConsole console) { + if (console.equals(getCurrentConsole())) { + // Already displayed + return; + } + + DebuggerConsoleWorkbenchPart part = fConsoleToPart.get(console); + if (part != null) { + partActivated(part); + } + } + + @Override + protected IWorkbenchPart getBootstrapPart() { + return null; + } + + /** + * Registers the given runnable with the display associated with this view's + * control, if any. + * + * @param r the runnable + * @see org.eclipse.swt.widgets.Display#asyncExec(java.lang.Runnable) + */ + private void asyncExec(Runnable r) { + if (isAvailable()) { + getPageBook().getDisplay().asyncExec(r); + } + } + + /** + * Initialize the PageSwitcher. + * The page switcher is triggered using a keyboard shortcut + * configured in the user's eclipse and allows to switch + * pages using a popup. + */ + private void initPageSwitcher() { + new PageSwitcher(this) { + @Override + public void activatePage(Object page) { + getConsoleManager().showConsoleView((IDebuggerConsole)page); + } + + @Override + public ImageDescriptor getImageDescriptor(Object page) { + return ((IDebuggerConsole)page).getImageDescriptor(); + } + + @Override + public String getName(Object page) { + return ((IDebuggerConsole)page).getName(); + } + + @Override + public Object[] getPages() { + return getConsoleManager().getConsoles(); + } + + @Override + public int getCurrentPageIndex() { + IConsole currentConsole = getCurrentConsole(); + IConsole[] consoles = getConsoleManager().getConsoles(); + for (int i = 0; i < consoles.length; i++) { + if (consoles[i].equals(currentConsole)) { + return i; + } + } + return super.getCurrentPageIndex(); + } + }; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleWorkbenchPart.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleWorkbenchPart.java new file mode 100644 index 00000000000..5abfff5bbfc --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleWorkbenchPart.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views.debuggerconsole; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.console.IConsole; + +/** + * Fake part to use as keys in page book for debugger console pages + */ +public class DebuggerConsoleWorkbenchPart implements IWorkbenchPart { + + private IConsole fConsole; + private IWorkbenchPartSite fSite; + + @Override + public boolean equals(Object obj) { + return (obj instanceof DebuggerConsoleWorkbenchPart) && + fConsole.equals(((DebuggerConsoleWorkbenchPart)obj).fConsole); + } + + @Override + public int hashCode() { + return fConsole.hashCode(); + } + + /** + * Constructs a part for the given console that binds to the given + * site + */ + public DebuggerConsoleWorkbenchPart(IConsole console, IWorkbenchPartSite site) { + fConsole = console; + fSite = site; + } + + @Override + public void addPropertyListener(IPropertyListener listener) { + } + + @Override + public void createPartControl(Composite parent) { + } + + @Override + public void dispose() { + } + + @Override + public IWorkbenchPartSite getSite() { + return fSite; + } + + @Override + public String getTitle() { + return ""; //$NON-NLS-1$ + } + + @Override + public Image getTitleImage() { + return null; + } + + @Override + public String getTitleToolTip() { + return ""; //$NON-NLS-1$ + } + + @Override + public void removePropertyListener(IPropertyListener listener) { + } + + @Override + public void setFocus() { + } + + @Override + public <T> T getAdapter(Class<T> adapter) { + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerShowConsoleAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerShowConsoleAction.java new file mode 100644 index 00000000000..baa43b20ae2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerShowConsoleAction.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views.debuggerconsole; + +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.jface.action.Action; + +/** + * Shows a specific console in the DebuggerConsoleView + */ +public class DebuggerShowConsoleAction extends Action { + + private IDebuggerConsole fConsole; + private DebuggerConsoleView fView; + + @Override + public void run() { + showConsole(fConsole, fView); + } + + /** + * Shows the given console in the given console view. + * + * @param console the console to show + * @param consoleView the console view + */ + public static void showConsole(IDebuggerConsole console, DebuggerConsoleView consoleView) { + if (!console.equals(consoleView.getCurrentConsole())) { + consoleView.display(console); + } + } + + /** + * Constructs an action to display the given console. + * + * @param view the console view in which the given console is contained + * @param console the console + */ + public DebuggerShowConsoleAction(DebuggerConsoleView view, IDebuggerConsole console) { + super(console.getName(), AS_RADIO_BUTTON); + fConsole = console; + fView = view; + setImageDescriptor(console.getImageDescriptor()); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java index 0e5d387606a..5c6f93bfc81 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java @@ -24,6 +24,8 @@ import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.breakpoints.CBreakpointUpdater; import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorManager; import org.eclipse.cdt.debug.internal.ui.pinclone.ViewIDCounterManager; +import org.eclipse.cdt.debug.internal.ui.views.debuggerconsole.DebuggerConsoleManager; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleManager; import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator; import org.eclipse.core.resources.IWorkspace; @@ -81,6 +83,8 @@ public class CDebugUIPlugin extends AbstractUIPlugin { private CDebugImageDescriptorRegistry fImageDescriptorRegistry; private DisassemblyEditorManager fDisassemblyEditorManager; + + private static IDebuggerConsoleManager fDebuggerConsoleManager; /** * The constructor. @@ -288,6 +292,8 @@ public class CDebugUIPlugin extends AbstractUIPlugin { fDisassemblyEditorManager = new DisassemblyEditorManager(); CDebugCorePlugin.getDefault().addCBreakpointListener( CBreakpointUpdater.getInstance() ); + fDebuggerConsoleManager = new DebuggerConsoleManager(); + WorkbenchJob wjob = new WorkbenchJob("Initializing CDT Debug UI") { //$NON-NLS-1$ @Override public IStatus runInUIThread(IProgressMonitor monitor) { @@ -397,4 +403,9 @@ public class CDebugUIPlugin extends AbstractUIPlugin { } return image; } + + /** @since 8.1 */ + public static IDebuggerConsoleManager getDebuggerConsoleManager() { + return fDebuggerConsoleManager; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java new file mode 100644 index 00000000000..09170b52b52 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.debuggerconsole; + +import org.eclipse.debug.core.ILaunch; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.part.IPageBookViewPage; + +/** + * @since 8.1 + */ +public interface IDebuggerConsole extends IConsole { + /** + * Returns the launch associated with this console. + * + * @return the launch associated with this console. + */ + ILaunch getLaunch(); + + /** + * Creates and returns a new page for this console. The page is displayed + * for this console in the console given view. + * + * @param view the view in which the page is to be created + * @return a page book view page representation of this console + */ + IPageBookViewPage createPage(IDebuggerConsoleView view); + + /** + * Request a re-computation of the name of the console. + */ + void resetName(); +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsoleManager.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsoleManager.java new file mode 100644 index 00000000000..a66c3cf6be6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsoleManager.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.debuggerconsole; + +import org.eclipse.ui.console.IConsoleListener; + +/** + * @since 8.1 + */ +public interface IDebuggerConsoleManager { + /** + * Registers the given listener for console notifications. Has + * no effect if an identical listener is already registered. + * + * @param listener listener to register + */ + public void addConsoleListener(IConsoleListener listener); + + /** + * Unregisters the given listener for console notifications. Has + * no effect if listener is not already registered. + * + * @param listener listener to unregister + */ + public void removeConsoleListener(IConsoleListener listener); + + /** + * Adds the given console to the console manager. Has no effect for + * equivalent consoles already registered. + * + * @param console console to add + */ + public void addConsole(IDebuggerConsole console); + + /** + * Removes the given console from the console manager. + * + * @param console console to remove + */ + public void removeConsole(IDebuggerConsole console); + + /** + * Returns a array of consoles registered with the console manager. + * + * @return an array of consoles registered with the console manager + */ + public IDebuggerConsole[] getConsoles(); + + /** + * Opens the console view and displays given the console. + * If the view is already open, it is brought to the front. + * Has no effect if the given console is not currently registered. + * + * @param console console to display + */ + public void showConsoleView(IDebuggerConsole console); +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsoleView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsoleView.java new file mode 100644 index 00000000000..ca5eb49ffac --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsoleView.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.debuggerconsole; + +import org.eclipse.ui.IViewPart; + +/** + * @since 8.1 + */ +public interface IDebuggerConsoleView extends IViewPart { + /** + * Displays the page for the given console in this console view. + * + * @param console console to display, cannot be <code>null</code> + */ + void display(IDebuggerConsole console); + + /** + * Returns the console currently being displayed, or <code>null</code> + * if none + * + * @return the console currently being displayed, or <code>null</code> + * if none + */ + IDebuggerConsole getCurrentConsole(); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml index 7d0180058cb..50250de53d6 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml @@ -515,10 +515,7 @@ class="org.eclipse.cdt.dsf.gdb.internal.ui.console.ConsolePageParticipant" id="org.eclipse.cdt.dsf.gdb.ui.dsfGdbConsolePageParticipant"> <enablement> - <or> <instanceof value="org.eclipse.ui.console.IOConsole"/> - <instanceof value="org.eclipse.cdt.dsf.gdb.internal.ui.console.GdbCliConsole"/> - </or> </enablement> </consolePageParticipant> </extension> diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java index 5468fa6045c..b65ba1b147b 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbUIPlugin.java @@ -89,6 +89,10 @@ public class GdbUIPlugin extends AbstractUIPlugin { fgBundleContext = null; } + public static GdbCliConsoleManager getCliConsoleManager() { + return fGdbConsoleManager; + } + /** * Dispose adapter sets for all launches. */ 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 73b3dfa60db..7394849ac52 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 @@ -57,8 +57,7 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).addDebugContextListener(this); } - if (console instanceof TracingConsole || - (isConsoleGdbCli(console) && console instanceof TextConsole)) { + if(console instanceof TracingConsole || isConsoleGdbCli(console)) { TextConsole textConsole = (TextConsole) console; // Add the save console action @@ -73,6 +72,7 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo /** * Checks if the the console is the gdb CLI. We don't rely on the attached * process name. Instead we check if the process is an instance of GDBProcess + * This gdb CLI console will only be used if the full GDB console is not available. * * @param console The console to check * @return true if the the console is the gdb CLI @@ -82,9 +82,6 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo org.eclipse.debug.ui.console.IConsole debugConsole = (org.eclipse.debug.ui.console.IConsole)console; return (debugConsole.getProcess() instanceof GDBProcess); } - if (console instanceof GdbCliConsole) { - return true; - } return false; } @@ -157,7 +154,7 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo } if (context instanceof GDBProcess) { - return (GDBProcess)context; + return (GDBProcess)context; } if (context != null) { @@ -198,15 +195,6 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo @Override public void debugContextChanged(DebugContextEvent event) { if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { - if (fView != null && fConsole instanceof GdbCliConsole) { - IProcess currentProcess = getCurrentProcess(); - if (currentProcess instanceof GDBProcess && - ((GdbCliConsole)fConsole).getLaunch().equals(currentProcess.getLaunch())) { - fView.display(fConsole); - } - return; - } - IProcess consoleProcess = getConsoleProcess(); if (fView != null && consoleProcess != null && consoleProcess.equals(getCurrentProcess())) { fView.display(fConsole); @@ -214,3 +202,4 @@ public class ConsolePageParticipant implements IConsolePageParticipant, IDebugCo } } } + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java index 68f1e820803..564a0f71303 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java @@ -7,6 +7,8 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.console; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleView; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; @@ -22,7 +24,7 @@ import org.eclipse.ui.part.IPageBookViewPage; * full-featured CLI interface. This is only supported with GDB >= 7.12 * and if IGDBBackend.isFullGdbConsoleSupported() returns true. */ -public class GdbCliConsole extends AbstractConsole { +public class GdbCliConsole extends AbstractConsole implements IDebuggerConsole { private final ILaunch fLaunch; private String fLabel; @@ -34,9 +36,11 @@ public class GdbCliConsole extends AbstractConsole { resetName(); } + @Override public ILaunch getLaunch() { return fLaunch; } - public void resetName() { + @Override + public void resetName() { String newName = computeName(); String name = getName(); if (!name.equals(newName)) { @@ -71,10 +75,16 @@ public class GdbCliConsole extends AbstractConsole { return label; } + + @Override + public IPageBookViewPage createPage(IDebuggerConsoleView view) { + view.setFocus(); + return new GdbCliConsolePage(this, view); + } - @Override + @Override public IPageBookViewPage createPage(IConsoleView view) { - view.setFocus(); - return new GdbCliConsolePage(this); - } + // This console is not used in the IConsoleView + return null; + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java index b61a7b194e4..54303051f50 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java @@ -12,6 +12,9 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.console; import java.util.concurrent.RejectedExecutionException; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleManager; import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; @@ -26,9 +29,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener2; -import org.eclipse.ui.console.ConsolePlugin; -import org.eclipse.ui.console.IConsole; -import org.eclipse.ui.console.IConsoleManager; /** * A console manager for GDB sessions which adds and removes @@ -55,20 +55,12 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { public void shutdown() { DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); - removeAllCliConsoles(); - } - - protected void removeAllCliConsoles() { - ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); - for (ILaunch launch : launches) { - removeCliConsole(launch); - } } @Override public void launchesAdded(ILaunch[] launches) { for (ILaunch launch : launches) { - addCliConsole(launch); + handleConsoleForLaunch(launch); } } @@ -79,66 +71,70 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { @Override public void launchesRemoved(ILaunch[] launches) { for (ILaunch launch : launches) { - removeCliConsole(launch); + removeConsole(launch); } } @Override public void launchesTerminated(ILaunch[] launches) { for (ILaunch launch : launches) { - renameCliConsole(launch); + renameConsole(launch); } } - protected void addCliConsole(ILaunch launch) { + protected void handleConsoleForLaunch(ILaunch launch) { // Full CLI GDB consoles are only added for GdbLaunches if (launch instanceof GdbLaunch) { - new GdbCliConsoleCreator((GdbLaunch)launch).init(); + new GdbConsoleCreator((GdbLaunch)launch).init(); } } - protected void removeCliConsole(ILaunch launch) { - GdbCliConsole console = getCliConsole(launch); + protected void removeConsole(ILaunch launch) { + IDebuggerConsole console = getConsole(launch); if (console != null) { - ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[]{console}); + removeConsole(console); } } - protected void renameCliConsole(ILaunch launch) { - GdbCliConsole console = getCliConsole(launch); + private void renameConsole(ILaunch launch) { + IDebuggerConsole console = getConsole(launch); if (console != null) { console.resetName(); } } - private GdbCliConsole getCliConsole(ILaunch launch) { - ConsolePlugin plugin = ConsolePlugin.getDefault(); - if (plugin != null) { - // This plugin can be null when running headless JUnit tests - IConsoleManager manager = plugin.getConsoleManager(); - IConsole[] consoles = manager.getConsoles(); - for (IConsole console : consoles) { - if (console instanceof GdbCliConsole) { - GdbCliConsole gdbConsole = (GdbCliConsole)console; - if (gdbConsole.getLaunch().equals(launch)) { - return gdbConsole; - } - } + private IDebuggerConsole getConsole(ILaunch launch) { + IDebuggerConsoleManager manager = CDebugUIPlugin.getDebuggerConsoleManager(); + for (IDebuggerConsole console : manager.getConsoles()) { + if (console.getLaunch().equals(launch)) { + return console; } } return null; } + private void addConsole(IDebuggerConsole console) { + getDebuggerConsoleManager().addConsole(console); + } + + private void removeConsole(IDebuggerConsole console) { + getDebuggerConsoleManager().removeConsole(console); + } + + private IDebuggerConsoleManager getDebuggerConsoleManager() { + return CDebugUIPlugin.getDebuggerConsoleManager(); + } + /** * Class that determines if a GdbCliConsole should be created for * this particular Gdblaunch. It figures this out by asking the * Backend service. */ - private class GdbCliConsoleCreator { + private class GdbConsoleCreator { private GdbLaunch fLaunch; private DsfSession fSession; - public GdbCliConsoleCreator(GdbLaunch launch) { + public GdbConsoleCreator(GdbLaunch launch) { fLaunch = launch; fSession = launch.getSession(); } @@ -156,10 +152,10 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { if (backend != null) { // Backend service already available, us it! - verifyAndCreateCliConsole(backend); + verifyAndCreateConsole(backend); } else { // Backend service not available yet, let's wait for it to start. - fSession.addServiceEventListener(new GdbBackendStartedListener(GdbCliConsoleCreator.this, fSession), null); + fSession.addServiceEventListener(new GdbBackendStartedListener(GdbConsoleCreator.this, fSession), null); } } }); @@ -168,7 +164,7 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { } @ConfinedToDsfExecutor("fSession.getExecutor()") - private void verifyAndCreateCliConsole(IGDBBackend backend) { + private void verifyAndCreateConsole(IGDBBackend backend) { if (backend != null && backend.isFullGdbConsoleSupported()) { // Create an new Cli console . String gdbVersion; @@ -180,15 +176,14 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { } String consoleTitle = fLaunch.getGDBPath().toOSString().trim() + " (" + gdbVersion +")"; //$NON-NLS-1$ //$NON-NLS-2$ - GdbCliConsole console = new GdbCliConsole(fLaunch, consoleTitle); - - // Register this console - ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{console}); + IDebuggerConsole console = new GdbCliConsole(fLaunch, consoleTitle); + addConsole(console); - // Very important to make sure the console view is open or else things will not work - ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console); - } - // Else, not the right type of backend service, or the service said not to start a GdbCliConsole + // Make sure the Debugger Console view is visible + getDebuggerConsoleManager().showConsoleView(console); + } + // Else, not the right type of backend service, or + // the service said not to start a GdbCliConsole } @ConfinedToDsfExecutor("fSession.getExecutor()") @@ -197,7 +192,7 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { IGDBBackend backend = tracker.getService(IGDBBackend.class); tracker.dispose(); - verifyAndCreateCliConsole(backend); + verifyAndCreateConsole(backend); } } @@ -208,9 +203,9 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { */ public class GdbBackendStartedListener { private DsfSession fSession; - private GdbCliConsoleCreator fCreator; + private GdbConsoleCreator fCreator; - public GdbBackendStartedListener(GdbCliConsoleCreator creator, DsfSession session) { + public GdbBackendStartedListener(GdbConsoleCreator creator, DsfSession session) { fCreator = creator; fSession = session; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java index c3600129d85..625c822bd26 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java @@ -13,13 +13,19 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.RejectedExecutionException; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleView; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; @@ -37,18 +43,23 @@ import org.eclipse.tm.terminal.view.ui.interfaces.ILauncherDelegate; import org.eclipse.tm.terminal.view.ui.launcher.LauncherDelegateManager; import org.eclipse.ui.part.Page; -public class GdbCliConsolePage extends Page { +public class GdbCliConsolePage extends Page implements IDebugContextListener { private DsfSession fSession; + private ILaunch fLaunch; private Composite fMainComposite; + private IDebuggerConsoleView fView; + private IDebuggerConsole fConsole; /** The control for the terminal widget embedded in the console */ private ITerminalViewControl fTerminalControl; - public GdbCliConsolePage(GdbCliConsole gdbConsole) { - ILaunch launch = gdbConsole.getLaunch(); - if (launch instanceof GdbLaunch) { - fSession = ((GdbLaunch)launch).getSession(); + public GdbCliConsolePage(GdbCliConsole gdbConsole, IDebuggerConsoleView view) { + fConsole = gdbConsole; + fView = view; + fLaunch = gdbConsole.getLaunch(); + if (fLaunch instanceof GdbLaunch) { + fSession = ((GdbLaunch)fLaunch).getSession(); } else { assert false; } @@ -57,6 +68,8 @@ public class GdbCliConsolePage extends Page { @Override public void dispose() { super.dispose(); + DebugUITools.getDebugContextManager().getContextService( + getSite().getWorkbenchWindow()).removeDebugContextListener(this); fTerminalControl.disposeTerminal(); } @@ -66,6 +79,9 @@ public class GdbCliConsolePage extends Page { fMainComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); fMainComposite.setLayout(new FillLayout()); + DebugUITools.getDebugContextManager().getContextService( + getSite().getWorkbenchWindow()).addDebugContextListener(this); + // Create the terminal control that will be used to interact with GDB fTerminalControl = TerminalViewControlFactory.makeControl( new ITerminalListener() { @@ -160,4 +176,28 @@ public class GdbCliConsolePage extends Page { new ITerminalServiceOutputStreamMonitorListener[0]); return properties; } + + /** + * Returns the launch to which the current selection belongs. + * + * @return the launch to which the current selection belongs. + */ + protected ILaunch getCurrentLaunch() { + IAdaptable context = DebugUITools.getDebugContext(); + if (context != null) { + return context.getAdapter(ILaunch.class); + } + return null; + } + + @Override + public void debugContextChanged(DebugContextEvent event) { + if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { + // Show this GDB console if it matches with the currently + // selected debug session + if (fLaunch.equals(getCurrentLaunch())) { + fView.display(fConsole); + } + } + } } diff --git a/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF b/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF index f9dc3e5f7f7..063efd80339 100644 --- a/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF +++ b/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF @@ -20,7 +20,7 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)", org.eclipse.cdt.core;bundle-version="[5.0.0,7.0.0)", org.eclipse.cdt.ui;bundle-version="[6.0.0,7.0.0)", org.eclipse.cdt.debug.core;bundle-version="[7.0.0,8.1.0)", - org.eclipse.cdt.debug.ui;bundle-version="[7.0.0,8.1.0)", + org.eclipse.cdt.debug.ui;bundle-version="[7.0.0,8.2.0)", org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)", org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)" |