blob: 9443cda587a6eb7d11e5da904e1ede670161cd00 [file] [log] [blame]
/*******************************************************************************
* 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.dsf.gdb.internal.ui.console;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import org.eclipse.cdt.debug.internal.ui.views.debuggerconsole.DebuggerConsoleView;
import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole;
import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleView;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbAutoTerminateAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsoleClearAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsoleCopyAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsolePasteAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsoleScrollLockAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsoleSelectAllAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsoleShowPreferencesAction;
import org.eclipse.cdt.dsf.gdb.internal.ui.console.actions.GdbConsoleTerminateLaunchAction;
import org.eclipse.cdt.utils.pty.PTY;
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.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.tm.internal.terminal.control.ITerminalListener;
import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
import org.eclipse.tm.internal.terminal.control.TerminalViewControlFactory;
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.Page;
/**
* Page used for a full GDB console. Each Debug session which uses the full GDB console will
* use its own instance of this page. GDB 7.12 is required to use the full GDB console.
*
* Contributions to this page's context menu can be done using id "GdbFullCliConsole.#ContextMenu".
* For example, using the extension point:<br>
* <code>
* menuContribution locationURI="popup:GdbFullCliConsole.#ContextMenu?after=additions"
* </code>
*/
public class GdbFullCliConsolePage extends Page implements IDebugContextListener {
private final ILaunch fLaunch;
private final PTY fGdbPty;
private Composite fMainComposite;
private final IDebuggerConsoleView fView;
private final IDebuggerConsole fConsole;
private final IGdbTerminalControlConnector fGdbTerminalControlConnector;
private MenuManager fMenuManager;
private GdbConsoleTerminateLaunchAction fTerminateLaunchAction;
/** The control for the terminal widget embedded in the console */
private ITerminalViewControl fTerminalControl;
private GdbConsoleClearAction fClearAction;
private GdbConsoleCopyAction fCopyAction;
private GdbConsolePasteAction fPasteAction;
private GdbConsoleScrollLockAction fScrollLockAction;
private GdbConsoleSelectAllAction fSelectAllAction;
private GdbAutoTerminateAction fAutoTerminateAction;
private GdbConsoleShowPreferencesAction fShowPreferencePageAction;
private GdbAbstractConsolePreferenceListener fPreferenceListener = new GdbAbstractConsolePreferenceListener() {
@Override
protected void handleAutoTerminatePref(boolean enabled) {
if (fAutoTerminateAction != null) {
fAutoTerminateAction.setChecked(enabled);
}
}
@Override
protected void handleInvertColorsPref(boolean enabled) {
setInvertedColors(enabled);
}
@Override
protected void handleBufferLinesPref(int bufferLines) {
setBufferLineLimit(bufferLines);
}
};
public GdbFullCliConsolePage(GdbFullCliConsole gdbConsole, IDebuggerConsoleView view, PTY pty) {
fConsole = gdbConsole;
fGdbTerminalControlConnector = gdbConsole.getTerminalControlConnector();
fView = view;
fLaunch = gdbConsole.getLaunch();
fGdbPty = pty;
GdbUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPreferenceListener);
}
@Override
public void dispose() {
super.dispose();
DebugUITools.getDebugContextManager().getContextService(
getSite().getWorkbenchWindow()).removeDebugContextListener(this);
fTerminalControl.disposeTerminal();
fMenuManager.dispose();
GdbUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPreferenceListener);
}
@Override
public void createControl(Composite parent) {
fMainComposite = new Composite(parent, SWT.NONE);
fMainComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
fMainComposite.setLayout(new FillLayout());
DebugUITools.getDebugContextManager().getContextService(
getSite().getWorkbenchWindow()).addDebugContextListener(this);
createTerminalControl();
createContextMenu();
configureToolBar(getSite().getActionBars().getToolBarManager());
}
private void setDefaults() {
IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
setInvertedColors(store.getBoolean(IGdbDebugPreferenceConstants.PREF_CONSOLE_INVERTED_COLORS));
setBufferLineLimit(store.getInt(IGdbDebugPreferenceConstants.PREF_CONSOLE_BUFFERLINES));
}
private void createTerminalControl() {
// Create the terminal control that will be used to interact with GDB
// Don't use common terminal preferences as GDB consoles are having their own
boolean useCommonPrefs = false;
fTerminalControl = TerminalViewControlFactory.makeControl(
new ITerminalListener() {
@Override public void setState(TerminalState state) {}
@Override public void setTerminalTitle(final String title) {}
},
fMainComposite,
new ITerminalConnector[] {},
useCommonPrefs);
fTerminalControl.setConnector(new GdbTerminalPageConnector(fGdbTerminalControlConnector, fGdbPty));
try {
fTerminalControl.setEncoding(Charset.defaultCharset().name());
} catch (UnsupportedEncodingException e) {
}
if (fTerminalControl instanceof ITerminalControl) {
((ITerminalControl)fTerminalControl).setConnectOnEnterIfClosed(false);
((ITerminalControl)fTerminalControl).setVT100LineWrapping(true);
}
// Must use syncExec because the logic within must complete before the rest
// of the class methods (specifically getProcess()) is called
fMainComposite.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
if (fTerminalControl != null && !fTerminalControl.isDisposed()) {
fTerminalControl.clearTerminal();
fTerminalControl.connectTerminal();
// The actual terminal widget initializes its defaults in the line above,
// lets override them with our application defaults right after.
setDefaults();
}
}
});
}
protected void createContextMenu() {
// Choose the id to be similar in format to what
// the GdbBasicCliConsole has as id, for consistency
String id = "GdbFullCliConsole.#ContextMenu"; //$NON-NLS-1$
fMenuManager = new MenuManager(id, id);
fMenuManager.setRemoveAllWhenShown(true);
fMenuManager.addMenuListener((menuManager) -> { contextMenuAboutToShow(menuManager); });
Menu menu = fMenuManager.createContextMenu(fTerminalControl.getControl());
fTerminalControl.getControl().setMenu(menu);
createActions();
getSite().registerContextMenu(id, fMenuManager, getSite().getSelectionProvider());
}
protected void createActions() {
fTerminateLaunchAction = new GdbConsoleTerminateLaunchAction(fLaunch);
fClearAction = new GdbConsoleClearAction(fTerminalControl);
fCopyAction = new GdbConsoleCopyAction(fTerminalControl);
fPasteAction = new GdbConsolePasteAction(fTerminalControl);
fScrollLockAction = new GdbConsoleScrollLockAction(fTerminalControl);
fSelectAllAction = new GdbConsoleSelectAllAction(fTerminalControl);
fAutoTerminateAction = new GdbAutoTerminateAction();
fShowPreferencePageAction = new GdbConsoleShowPreferencesAction(getSite().getShell());
}
protected void configureToolBar(IToolBarManager mgr) {
mgr.insertBefore(DebuggerConsoleView.DROP_DOWN_ACTION_ID, fTerminateLaunchAction);
mgr.insertBefore(DebuggerConsoleView.DROP_DOWN_ACTION_ID, fClearAction);
mgr.insertBefore(DebuggerConsoleView.DROP_DOWN_ACTION_ID, fScrollLockAction);
}
protected void contextMenuAboutToShow(IMenuManager menuManager) {
menuManager.add(fCopyAction);
menuManager.add(fPasteAction);
menuManager.add(fSelectAllAction);
menuManager.add(new Separator());
menuManager.add(fClearAction);
menuManager.add(new Separator());
menuManager.add(fScrollLockAction);
menuManager.add(new Separator());
menuManager.add(fTerminateLaunchAction);
menuManager.add(fAutoTerminateAction);
menuManager.add(new Separator());
// Other plug-ins can contribute their actions here
menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
menuManager.add(fShowPreferencePageAction);
}
@Override
public Control getControl() {
return fMainComposite;
}
@Override
public void setFocus() {
fTerminalControl.setFocus();
}
/**
* 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);
}
}
}
private void setInvertedColors(boolean enable) {
if (fTerminalControl != null) {
fTerminalControl.setInvertedColors(enable);
}
}
private void setBufferLineLimit(int bufferLines) {
if (fTerminalControl != null) {
fTerminalControl.setBufferLineLimit(bufferLines);
}
}
public ITerminalViewControl getTerminalViewControl() {
return fTerminalControl;
}
}