Java tutorial
/*=============================================================================# # Copyright (c) 2005-2015 Stephan Wahlbrink (WalWare.de) 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: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.statet.nico.ui.console; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler2; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.ListenerList; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.internal.ui.views.console.ConsoleRemoveAllTerminatedAction; import org.eclipse.debug.internal.ui.views.console.ConsoleRemoveLaunchAction; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuListener2; 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.dialogs.IDialogSettings; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.text.IFindReplaceTarget; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Rectangle; 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.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Sash; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.console.IConsoleConstants; import org.eclipse.ui.console.IConsoleView; import org.eclipse.ui.console.TextConsoleViewer; import org.eclipse.ui.console.actions.ClearOutputAction; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.part.IPageBookViewPage; import org.eclipse.ui.part.IPageSite; import org.eclipse.ui.part.IShowInSource; import org.eclipse.ui.part.IShowInTargetList; import org.eclipse.ui.part.ShowInContext; import org.eclipse.ui.services.IServiceLocator; import org.eclipse.ui.texteditor.FindReplaceAction; import de.walware.ecommons.ltk.ui.sourceediting.ISourceEditor; import de.walware.ecommons.ltk.ui.sourceediting.SourceEditorViewerConfigurator; import de.walware.ecommons.preferences.PreferencesUtil; import de.walware.ecommons.preferences.SettingsChangeNotifier.ChangeListener; import de.walware.ecommons.text.ui.TextViewerAction; import de.walware.ecommons.text.ui.TextViewerEditorColorUpdater; import de.walware.ecommons.ui.ISettingsChangedHandler; import de.walware.ecommons.ui.SharedMessages; import de.walware.ecommons.ui.SharedUIResources; import de.walware.ecommons.ui.actions.HandlerCollection; import de.walware.ecommons.ui.actions.HandlerContributionItem; import de.walware.ecommons.ui.actions.SimpleContributionItem; import de.walware.ecommons.ui.util.DNDUtil; import de.walware.ecommons.ui.util.DialogUtil; import de.walware.ecommons.ui.util.LayoutUtil; import de.walware.ecommons.ui.util.NestedServices; import de.walware.ecommons.ui.util.UIAccess; import de.walware.statet.nico.core.runtime.Prompt; import de.walware.statet.nico.core.runtime.ToolController; import de.walware.statet.nico.core.runtime.ToolProcess; import de.walware.statet.nico.core.runtime.ToolStatus; import de.walware.statet.nico.core.runtime.ToolWorkspace; import de.walware.statet.nico.core.util.IToolProvider; import de.walware.statet.nico.core.util.IToolRetargetable; import de.walware.statet.nico.internal.ui.LocalTaskTransfer; import de.walware.statet.nico.internal.ui.Messages; import de.walware.statet.nico.internal.ui.NicoUIPlugin; import de.walware.statet.nico.internal.ui.console.OutputViewer; import de.walware.statet.nico.ui.NicoUI; import de.walware.statet.nico.ui.actions.CancelHandler; import de.walware.statet.nico.ui.util.ExportConsoleOutputWizard; import de.walware.statet.nico.ui.util.NicoWizardDialog; import de.walware.statet.nico.ui.util.OpenTrackingFilesContributionItem; /** * A page for a <code>NIConsole</code>. * <p> * The page contains beside the usual output viewer * a separete input field with submit button. */ public abstract class NIConsolePage implements IPageBookViewPage, IAdaptable, IShowInSource, IShowInTargetList, IPropertyChangeListener, ScrollLockAction.Receiver, IToolProvider, ChangeListener { private static final String DIALOG_ID = "Console"; //$NON-NLS-1$ private static final String SETTING_INPUTHEIGHT = "InputHeight"; //$NON-NLS-1$ public static final String NICO_CONTROL_MENU_ID = "nico.control"; //$NON-NLS-1$ private class FindReplaceUpdater implements IDocumentListener { private boolean wasEmpty = true; @Override public void documentAboutToBeChanged(final DocumentEvent event) { } @Override public void documentChanged(final DocumentEvent event) { final boolean isEmpty = (event.fDocument.getLength() == 0); if (isEmpty != wasEmpty) { fMultiActionHandler.updateEnabledState(); wasEmpty = isEmpty; } } } private class PostUpdater implements IDocumentListener, Runnable { private volatile boolean fIsSheduled = false; @Override public void documentAboutToBeChanged(final DocumentEvent event) { } @Override public void documentChanged(final DocumentEvent event) { if (!fIsSheduled) { fIsSheduled = true; final Display display = UIAccess.getDisplay(getSite().getShell()); display.asyncExec(this); } } @Override public void run() { // post change run fIsSheduled = false; fMultiActionHandler.updateEnabledState(); } } private class SizeController implements Listener { private final Sash fSash; private final GridData fOutputGD; private final GridData fInputGD; private int fLastExplicit; public SizeController(final Sash sash, final GridData outputGD, final GridData inputGD) { fSash = sash; fOutputGD = outputGD; fInputGD = inputGD; fLastExplicit = -1; } @Override public void handleEvent(final Event event) { if (event.widget == fSash) { if (event.type == SWT.Selection && event.detail != SWT.DRAG) { final Rectangle bounds = fControl.getClientArea(); // System.out.println(bounds.height); // Rectangle bounds2 = fInputGroup.getComposite().getBounds(); // System.out.println(bounds2.y+bounds2.height); setNewInputHeight(bounds.height - event.y - fSash.getSize().y, true); } return; } if (event.widget == fControl) { if (event.type == SWT.Resize) { setNewInputHeight(fInputGD.heightHint, false); } } } private void setNewInputHeight(int height, final boolean explicit) { if (!explicit) { height = fLastExplicit; } if (height == -1) { return; } final Rectangle bounds = fControl.getClientArea(); final int max = bounds.height - fOutputGD.minimumHeight - fSash.getSize().y; if (height > max) { height = max; } if (height < fInputGD.minimumHeight) { height = -1; } if (explicit) { fLastExplicit = height; } if (fInputGD.heightHint == height) { return; } fInputGD.heightHint = height; fControl.layout(new Control[] { fInputGroup.getComposite() }); } private void fontChanged() { fOutputGD.minimumHeight = LayoutUtil.hintHeight(fOutputViewer.getTextWidget(), 4); final ScrollBar bar = fOutputViewer.getTextWidget().getHorizontalBar(); if (bar.isVisible()) { fOutputGD.minimumHeight += bar.getSize().y; } fInputGD.minimumHeight = fInputGroup.getComposite().computeSize(800, -1).y; if (fInputGD.heightHint != -1 && fInputGD.minimumHeight > fInputGD.heightHint) { fInputGD.heightHint = -1; } } } private class StatusListener implements IDebugEventSetListener { private boolean isProcessing = false; private boolean isTerminated = false; private int updateId = Integer.MIN_VALUE; private Prompt fNewPrompt = null; private boolean fCurrentBusy = false; private boolean fNewBusy = false; public void init() { final ToolController controller = getConsole().getProcess().getController(); synchronized (StatusListener.this) { if (controller != null) { final ToolStatus status = controller.getStatus(); isProcessing = (status == ToolStatus.STARTED_PROCESSING || status == ToolStatus.STARTING); isTerminated = (status == ToolStatus.TERMINATED); fCurrentBusy = fNewBusy = (isProcessing || isTerminated); } else { isProcessing = false; isTerminated = true; fCurrentBusy = fNewBusy = true; } fInputGroup.updatePrompt(null); fInputGroup.updateBusy(fCurrentBusy); } } @Override public void handleDebugEvents(final DebugEvent[] events) { final ToolProcess process = getConsole().getProcess(); final ToolWorkspace data = process.getWorkspaceData(); Prompt prompt = null; boolean match = false; for (final DebugEvent event : events) { final Object source = event.getSource(); if (source == process) { switch (event.getKind()) { case DebugEvent.TERMINATE: match = true; isTerminated = true; onToolTerminated(); break; case DebugEvent.MODEL_SPECIFIC: match = true; final int type = (event.getDetail() & ToolProcess.TYPE_MASK); if (type == ToolProcess.STATUS) { isProcessing = (event.getDetail() == ToolProcess.STATUS_PROCESS); } break; } } else if (source == data) { if (event.getKind() == DebugEvent.CHANGE && event.getDetail() == ToolWorkspace.DETAIL_PROMPT) { match = true; prompt = (Prompt) event.getData(); } } } if (!match) { return; } final int thisId; final long schedule; synchronized (StatusListener.this) { fNewBusy = isProcessing || isTerminated; schedule = (fNewBusy) ? (System.nanoTime() + 50000000L) : System.nanoTime(); if (prompt != null) { fNewPrompt = prompt; } if (!fIsCreated || (fNewBusy == fCurrentBusy && fNewPrompt == null)) { return; } thisId = ++updateId; } UIAccess.getDisplay().asyncExec(new Runnable() { @Override public void run() { final long diff = (schedule - System.nanoTime()) / 1000000L; if (diff > 5) { Display.getCurrent().timerExec((int) diff, this); return; } if (!fIsCreated) { return; } synchronized (StatusListener.this) { if (thisId != updateId) { return; } if (fNewPrompt != null) { fInputGroup.updatePrompt(fNewPrompt); fNewPrompt = null; } if (fNewBusy != fCurrentBusy) { fInputGroup.updateBusy(fNewBusy); fCurrentBusy = fNewBusy; } } }; }); } } private final NIConsole fConsole; private final IConsoleView fConsoleView; private IPageSite fSite; private Composite fControl; private Clipboard fClipboard; private OutputViewer fOutputViewer; private ConsolePageEditor fInputGroup; private SizeController fResizer; private MenuManager fOutputMenuManager; private MenuManager fInputMenuManager; private volatile boolean fIsCreated = false; // Actions private MultiActionHandler fMultiActionHandler; private final ListenerList fToolActions = new ListenerList(); NestedServices fInputServices; private FindReplaceUpdater fFindReplaceUpdater; private FindReplaceAction fFindReplaceAction; // Output viewer actions private TextViewerAction fOutputCopyAction; private SubmitPasteAction fOutputPasteAction; private TextViewerAction fOutputSelectAllAction; private ClearOutputAction fOutputClearAllAction; private Action fOutputScrollLockAction; // Input viewer actions private TextViewerAction fInputDeleteAction; private TextViewerAction fInputCutAction; private TextViewerAction fInputCopyAction; private TextViewerAction fInputPasteAction; private TextViewerAction fInputSelectAllAction; private TextViewerAction fInputUndoAction; private TextViewerAction fInputRedoAction; // Process control actions private StatusListener fDebugListener; private ConsoleRemoveLaunchAction fRemoveAction; private ConsoleRemoveAllTerminatedAction fRemoveAllAction; private TerminateToolAction fTerminateAction; private final HandlerCollection fPageHandlers = new HandlerCollection(); private final HandlerCollection fInputHandlers = new HandlerCollection(); /** * Constructs a console page for the given console in the given view. * * @param console the console * @param view the console view the page is contained in */ public NIConsolePage(final NIConsole console, final IConsoleView view) { fConsole = console; fConsoleView = view; } @Override public void init(final IPageSite site) throws PartInitException { fSite = site; fInputGroup = createInputGroup(); fDebugListener = new StatusListener(); DebugPlugin.getDefault().addDebugEventListener(fDebugListener); } protected ConsolePageEditor createInputGroup() { return new ConsolePageEditor(this); } protected ConsolePageEditor getInputGroup() { return fInputGroup; } @Override public void createControl(final Composite parent) { PreferencesUtil.getSettingsChangeNotifier().addChangeListener(this); fConsole.addPropertyChangeListener(this); fControl = new Composite(parent, SWT.NONE) { @Override public boolean setFocus() { NIConsolePage.this.setFocus(); return true; } @Override public void setVisible(final boolean visible) { super.setVisible(visible); if (visible) { NIConsolePage.this.setFocus(); } } }; final GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.verticalSpacing = 0; layout.marginWidth = 0; fControl.setLayout(layout); fOutputViewer = new OutputViewer(fControl, fConsole); final GridData outputGD = new GridData(SWT.FILL, SWT.FILL, true, true); fOutputViewer.getControl().setLayoutData(outputGD); new TextViewerEditorColorUpdater(fOutputViewer, EditorsUI.getPreferenceStore()); fOutputViewer.getTextWidget().addKeyListener(new KeyListener() { @Override public void keyPressed(final KeyEvent e) { if (e.doit && (e.character > 0) && (e.stateMask == SWT.NONE || e.stateMask == SWT.SHIFT) && ((e.keyCode & SWT.KEYCODE_BIT) == 0)) { final StyledText textWidget = fInputGroup.getViewer().getTextWidget(); if (!UIAccess.isOkToUse(textWidget)) { return; } final int cType = Character.getType(e.character); if (cType > 0 && cType < Character.CONTROL && textWidget.getCharCount() == 0) { textWidget.replaceTextRange(0, 0, Character.toString(e.character)); textWidget.setCaretOffset(textWidget.getCharCount()); } else { Display.getCurrent().beep(); } setFocus(); } } @Override public void keyReleased(final KeyEvent e) { } }); final Sash sash = new Sash(fControl, SWT.HORIZONTAL); // sash.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); fInputGroup.createControl(fControl, createInputEditorConfigurator()); final GridData inputGD = new GridData(SWT.FILL, SWT.FILL, true, false); fInputGroup.getComposite().setLayoutData(inputGD); fOutputViewer.getTextWidget().getHorizontalBar().setVisible(false); fResizer = new SizeController(sash, outputGD, inputGD); sash.addListener(SWT.Selection, fResizer); fControl.addListener(SWT.Resize, fResizer); fClipboard = new Clipboard(fControl.getDisplay()); createActions(); initActions(getSite(), fPageHandlers); fInputGroup.initActions(fInputServices.getLocator(), fInputHandlers); hookContextMenu(); hookDND(); contributeToActionBars(getSite(), getSite().getActionBars(), fPageHandlers); new ConsoleActivationNotifier(); fIsCreated = true; fDebugListener.init(); final IDialogSettings dialogSettings = DialogUtil.getDialogSettings(NicoUIPlugin.getDefault(), DIALOG_ID); try { final int height = dialogSettings.getInt(SETTING_INPUTHEIGHT); if (height > 0) { fResizer.fLastExplicit = height; } } catch (final NumberFormatException e) { // missing value } fResizer.fontChanged(); Display.getCurrent().asyncExec(new Runnable() { @Override public void run() { if (fInputGroup != null && UIAccess.isOkToUse(fInputGroup.getViewer())) { fOutputViewer.revealEndOfDocument(); if (fOutputViewer.getControl().isFocusControl()) { setFocus(); } } } }); } /** * Creates the adapter to configure the input source viewer. * Will be disposed automatically. * * @return the adapter */ protected abstract SourceEditorViewerConfigurator createInputEditorConfigurator(); private class ConsoleActivationNotifier implements Listener { private ConsoleActivationNotifier() { fControl.addListener(SWT.Activate, this); fControl.addListener(SWT.Dispose, this); if (fControl.isVisible()) { NicoUIPlugin.getDefault().getToolRegistry().consoleActivated(fConsoleView, fConsole); } } @Override public void handleEvent(final Event event) { switch (event.type) { case SWT.Activate: NicoUIPlugin.getDefault().getToolRegistry().consoleActivated(fConsoleView, fConsole); break; case SWT.Dispose: fControl.removeListener(SWT.Activate, this); fControl.removeListener(SWT.Dispose, this); break; } } } private void createActions() { final Control outputControl = fOutputViewer.getControl(); final SourceViewer inputViewer = fInputGroup.getViewer(); final Control inputControl = inputViewer.getControl(); final IServiceLocator pageServiceLocator = getSite(); fInputServices = new NestedServices(pageServiceLocator, "ConsoleInput"); fInputServices.bindTo(inputControl); final IHandlerService pageHandlerService = (IHandlerService) pageServiceLocator .getService(IHandlerService.class); final IHandlerService inputHandlerService = (IHandlerService) fInputServices.getLocator() .getService(IHandlerService.class); fMultiActionHandler = new MultiActionHandler(); fRemoveAction = new ConsoleRemoveLaunchAction(fConsole.getProcess().getLaunch()); fRemoveAllAction = new ConsoleRemoveAllTerminatedAction(); fTerminateAction = new TerminateToolAction(fConsole.getProcess()); { final IHandler2 handler = new CancelHandler(this, ToolController.CANCEL_CURRENT); fPageHandlers.add(NicoUI.CANCEL_CURRENT_COMMAND_ID, handler); pageHandlerService.activateHandler(NicoUI.CANCEL_CURRENT_COMMAND_ID, handler); } { final IHandler2 handler = new CancelHandler(this, ToolController.CANCEL_ALL); fPageHandlers.add(NicoUI.CANCEL_ALL_COMMAND_ID, handler); pageHandlerService.activateHandler(NicoUI.CANCEL_ALL_COMMAND_ID, handler); } { final IHandler2 handler = new CancelHandler(this, ToolController.CANCEL_CURRENT | ToolController.CANCEL_PAUSE); fPageHandlers.add(NicoUI.CANCEL_PAUSE_COMMAND_ID, handler); pageHandlerService.activateHandler(NicoUI.CANCEL_PAUSE_COMMAND_ID, handler); } // Conflict with binding CTRL+Z (in console EOF) // pageKeys.activateContext("org.eclipse.debug.ui.console"); //$NON-NLS-1$ fOutputCopyAction = TextViewerAction.createCopyAction(fOutputViewer); fMultiActionHandler.addGlobalAction(outputControl, ActionFactory.COPY.getId(), fOutputCopyAction); fOutputPasteAction = new SubmitPasteAction(this); fOutputPasteAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_PASTE); fMultiActionHandler.addGlobalAction(outputControl, ActionFactory.PASTE.getId(), fOutputPasteAction); fOutputSelectAllAction = TextViewerAction.createSelectAllAction(fOutputViewer); fMultiActionHandler.addGlobalAction(outputControl, ActionFactory.SELECT_ALL.getId(), fOutputSelectAllAction); fOutputClearAllAction = new ClearOutputAction(fConsole); fOutputScrollLockAction = new ScrollLockAction(this, false); fInputDeleteAction = TextViewerAction.createDeleteAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.DELETE.getId(), fInputDeleteAction); fInputCutAction = TextViewerAction.createCutAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.CUT.getId(), fInputCutAction); fInputCopyAction = TextViewerAction.createCopyAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.COPY.getId(), fInputCopyAction); fInputPasteAction = TextViewerAction.createPasteAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.PASTE.getId(), fInputPasteAction); fInputSelectAllAction = TextViewerAction.createSelectAllAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.SELECT_ALL.getId(), fInputSelectAllAction); fInputUndoAction = TextViewerAction.createUndoAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.UNDO.getId(), fInputUndoAction); fInputRedoAction = TextViewerAction.createRedoAction(inputViewer); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.REDO.getId(), fInputRedoAction); final ResourceBundle bundle = SharedMessages.getCompatibilityBundle(); fFindReplaceAction = new FindReplaceAction(bundle, "FindReplaceAction_", fConsoleView); //$NON-NLS-1$ fFindReplaceAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE); fMultiActionHandler.addGlobalAction(outputControl, ActionFactory.FIND.getId(), fFindReplaceAction); fMultiActionHandler.addGlobalAction(inputControl, ActionFactory.FIND.getId(), fFindReplaceAction); fFindReplaceUpdater = new FindReplaceUpdater(); fConsole.getDocument().addDocumentListener(fFindReplaceUpdater); inputViewer.getDocument().addDocumentListener(new PostUpdater()); inputViewer.addSelectionChangedListener(fMultiActionHandler); fOutputViewer.addSelectionChangedListener(fMultiActionHandler); } protected void initActions(final IServiceLocator serviceLocator, final HandlerCollection handlers) { } private void hookContextMenu() { String id = NIConsole.NICONSOLE_TYPE + "#OutputContextMenu"; //$NON-NLS-1$ fOutputMenuManager = new MenuManager("ContextMenu", id); //$NON-NLS-1$ fOutputMenuManager.setRemoveAllWhenShown(true); fOutputMenuManager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(final IMenuManager manager) { fillOutputContextMenu(manager); } }); Control control = fOutputViewer.getControl(); Menu menu = fOutputMenuManager.createContextMenu(control); control.setMenu(menu); getSite().registerContextMenu(id, fOutputMenuManager, fOutputViewer); id = NIConsole.NICONSOLE_TYPE + "#InputContextMenu"; //$NON-NLS-1$ fInputMenuManager = new MenuManager("ContextMenu", id); //$NON-NLS-1$ fInputMenuManager.setRemoveAllWhenShown(true); fInputMenuManager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(final IMenuManager manager) { fillInputContextMenu(manager); } }); control = fInputGroup.getViewer().getControl(); menu = fInputMenuManager.createContextMenu(control); control.setMenu(menu); getSite().registerContextMenu(id, fInputMenuManager, fInputGroup.getViewer()); } protected void hookDND() { DNDUtil.addDropSupport(fOutputViewer.getControl(), new SubmitDropAdapter(this), new Transfer[] { TextTransfer.getInstance(), LocalTaskTransfer.getTransfer() }); } protected void contributeToActionBars(final IServiceLocator serviceLocator, final IActionBars actionBars, final HandlerCollection handlers) { fMultiActionHandler.registerActions(actionBars); final IToolBarManager toolBarManager = actionBars.getToolBarManager(); toolBarManager.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fOutputClearAllAction); toolBarManager.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fOutputScrollLockAction); toolBarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, new HandlerContributionItem( new CommandContributionItemParameter(serviceLocator, CancelHandler.MENU_ID, NicoUI.CANCEL_CURRENT_COMMAND_ID, null, null, null, null, Messages.CancelAction_name, null, Messages.CancelAction_tooltip, HandlerContributionItem.STYLE_PULLDOWN, null, false), fPageHandlers.get(NicoUI.CANCEL_CURRENT_COMMAND_ID)) { // Workaround for E-Bug #366528 @Override protected void initDropDownMenu(final MenuManager menuManager) { menuManager.addMenuListener(new IMenuListener2() { @Override public void menuAboutToShow(final IMenuManager manager) { manager.add(new CommandContributionItem(new CommandContributionItemParameter(serviceLocator, null, NicoUI.CANCEL_CURRENT_COMMAND_ID, CommandContributionItem.STYLE_PUSH))); manager.add(new CommandContributionItem(new CommandContributionItemParameter(serviceLocator, null, NicoUI.CANCEL_PAUSE_COMMAND_ID, CommandContributionItem.STYLE_PUSH))); manager.add(new CommandContributionItem(new CommandContributionItemParameter(serviceLocator, null, NicoUI.CANCEL_ALL_COMMAND_ID, CommandContributionItem.STYLE_PUSH))); } @Override public void menuAboutToHide(final IMenuManager manager) { display.asyncExec(new Runnable() { @Override public void run() { menuManager.dispose(); } }); } }); } }); toolBarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, fTerminateAction); toolBarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, fRemoveAction); toolBarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, fRemoveAllAction); final IMenuManager menuManager = actionBars.getMenuManager(); menuManager.add(new Separator(NICO_CONTROL_MENU_ID)); menuManager.add(new Separator(SharedUIResources.ADDITIONS_MENU_ID)); menuManager.add(new Separator("tracking")); //$NON-NLS-1$ final MenuManager trackingMenu = new MenuManager("Open In Editor") { @Override public boolean isVisible() { return !getTool().getTracks().isEmpty(); } }; trackingMenu.add(new OpenTrackingFilesContributionItem(getTool())); menuManager.add(trackingMenu); menuManager.add(new SimpleContributionItem("Export Console Output...", null) { @Override protected void execute() throws ExecutionException { final ToolProcess tool = getTool(); if (tool == null) { return; } final ExportConsoleOutputWizard wizard = new ExportConsoleOutputWizard(NIConsolePage.this); final WizardDialog dialog = new NicoWizardDialog(getSite().getShell(), wizard); dialog.setBlockOnOpen(false); dialog.open(); } }); menuManager.add(new Separator("settings")); //$NON-NLS-1$ menuManager.add(new SimpleContributionItem("Preferences...", "P") { @Override protected void execute() throws ExecutionException { final Shell shell = getSite().getShell(); final List<String> pageIds = new ArrayList<String>(); NIConsolePage.this.collectContextMenuPreferencePages(pageIds); if (!pageIds.isEmpty() && (shell == null || !shell.isDisposed())) { org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn(shell, pageIds.get(0), pageIds.toArray(new String[pageIds.size()]), null).open(); } } }); menuManager.add(new Separator()); } protected void fillInputContextMenu(final IMenuManager manager) { manager.add(fInputCutAction); manager.add(fInputCopyAction); manager.add(fInputPasteAction); manager.add(new GroupMarker(IWorkbenchActionConstants.CUT_EXT)); manager.add(new Separator()); manager.add(fInputUndoAction); manager.add(fInputRedoAction); manager.add(new GroupMarker(IWorkbenchActionConstants.UNDO_EXT)); manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } protected void fillOutputContextMenu(final IMenuManager manager) { manager.add(fOutputCopyAction); manager.add(fOutputSelectAllAction); manager.add(new Separator("more")); //$NON-NLS-1$ manager.add(fFindReplaceAction); // manager.add(new FollowHyperlinkAction(fViewer)); manager.add(new Separator("submit")); //$NON-NLS-1$ manager.add(fOutputPasteAction); manager.add(new Separator("view")); //$NON-NLS-1$ manager.add(fOutputClearAllAction); manager.add(fOutputScrollLockAction); manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } @Override public void dispose() { fConsole.removePropertyChangeListener(this); PreferencesUtil.getSettingsChangeNotifier().removeChangeListener(this); if (fDebugListener != null) { final DebugPlugin debug = DebugPlugin.getDefault(); if (debug != null) { debug.removeDebugEventListener(fDebugListener); } fDebugListener = null; } if (fIsCreated) { // control created fIsCreated = false; try { fConsole.getDocument().removeDocumentListener(fFindReplaceUpdater); fOutputViewer.removeSelectionChangedListener(fMultiActionHandler); fInputGroup.getViewer().removeSelectionChangedListener(fMultiActionHandler); } catch (final Exception e) { NicoUIPlugin.logError(NicoUIPlugin.INTERNAL_ERROR, Messages.Console_error_UnexpectedException_message, e); } fPageHandlers.dispose(); fInputHandlers.dispose(); fMultiActionHandler.dispose(); fMultiActionHandler = null; fInputServices.dispose(); fInputServices = null; fFindReplaceAction = null; fOutputCopyAction = null; fOutputPasteAction = null; fOutputSelectAllAction = null; fOutputClearAllAction = null; fInputDeleteAction = null; fInputCutAction = null; fInputCopyAction = null; fInputPasteAction = null; fInputSelectAllAction = null; fInputUndoAction = null; fDebugListener = null; fRemoveAction.dispose(); fRemoveAction = null; fRemoveAllAction.dispose(); fRemoveAllAction = null; fTerminateAction.dispose(); fTerminateAction = null; fOutputViewer = null; } if (fInputGroup != null) { fInputGroup.dispose(); fInputGroup = null; } } @Override public IPageSite getSite() { return fSite; } public IConsoleView getView() { return fConsoleView; } @Override public Control getControl() { return fControl; } public NIConsole getConsole() { return fConsole; } public Clipboard getClipboard() { return fClipboard; } @Override public ToolProcess getTool() { return fConsole.getProcess(); } @Override public void addToolRetargetable(final IToolRetargetable listener) { fToolActions.add(listener); } @Override public void removeToolRetargetable(final IToolRetargetable listener) { fToolActions.remove(listener); } public TextConsoleViewer getOutputViewer() { return fOutputViewer; } public IMenuManager getOutputContextMenuManager() { return fOutputMenuManager; } public IMenuManager getInputContextMenuManager() { return fInputMenuManager; } /** * Return the text in the input line. * * @return */ public String getInput() { return fInputGroup.fDocument.get(); } /** * Clear the input line (e.g. after successful submit). */ public void clearInput() { fInputGroup.clear(); } @Override public Object getAdapter(final Class required) { if (fInputGroup != null) { if (Widget.class.equals(required)) { if (fOutputViewer.getControl().isFocusControl()) { return fOutputViewer.getTextWidget(); } return fInputGroup.getViewer().getTextWidget(); } if (IFindReplaceTarget.class.equals(required)) { if (fInputGroup.getViewer().getControl().isFocusControl()) { return fInputGroup.getViewer().getFindReplaceTarget(); } return fOutputViewer.getFindReplaceTarget(); } } if (ISourceEditor.class.equals(required)) { return fInputGroup; } if (IShowInSource.class.equals(required)) { return this; } if (IShowInTargetList.class.equals(required)) { return this; } return fConsole.getAdapter(required); } @Override public ShowInContext getShowInContext() { final IProcess process = fConsole.getProcess(); if (process == null) { return null; } final IDebugTarget target = (IDebugTarget) process.getAdapter(IDebugTarget.class); ISelection selection = null; if (target == null) { selection = new TreeSelection(new TreePath( new Object[] { DebugPlugin.getDefault().getLaunchManager(), process.getLaunch(), process })); } else { selection = new TreeSelection(new TreePath( new Object[] { DebugPlugin.getDefault().getLaunchManager(), target.getLaunch(), target })); } return new ShowInContext(null, selection); } @Override public String[] getShowInTargetIds() { return new String[] { IDebugUIConstants.ID_DEBUG_VIEW }; } @Override public void setActionBars(final IActionBars actionBars) { // fOutputViewer.setActionBars(actionBars); } @Override public void setFocus() { fInputGroup.getViewer().getControl().setFocus(); } protected void onToolTerminated() { if (fIsCreated) { fTerminateAction.update(); for (final Object action : fToolActions.getListeners()) { ((IToolRetargetable) action).toolTerminated(); } fOutputPasteAction.setEnabled(false); final Button button = fInputGroup.getSubmitButton(); UIAccess.getDisplay(getSite().getShell()).asyncExec(new Runnable() { @Override public void run() { if (UIAccess.isOkToUse(button)) { button.setEnabled(false); } } }); final IDialogSettings dialogSettings = DialogUtil.getDialogSettings(NicoUIPlugin.getDefault(), DIALOG_ID); dialogSettings.put(SETTING_INPUTHEIGHT, fResizer.fLastExplicit); } } @Override public void setAutoScroll(final boolean enabled) { fOutputViewer.setAutoScroll(enabled); fOutputScrollLockAction.setChecked(!enabled); } @Override public void propertyChange(final PropertyChangeEvent event) { if (UIAccess.isOkToUse(fControl)) { final Object source = event.getSource(); final String property = event.getProperty(); if (source.equals(fConsole) && property.equals(IConsoleConstants.P_FONT)) { final Font font = fConsole.getFont(); fOutputViewer.setFont(font); fInputGroup.setFont(font); fResizer.fontChanged(); fControl.layout(); } else if (property.equals(IConsoleConstants.P_FONT_STYLE)) { fControl.redraw(); fOutputViewer.getTextWidget().redraw(); } else if (property.equals(IConsoleConstants.P_STREAM_COLOR)) { fOutputViewer.getTextWidget().redraw(); } // else if (source.equals(fConsole) && property.equals(IConsoleConstants.P_TAB_SIZE)) { // int tabSize = ((Integer) event.getNewValue()).intValue(); // fOutputViewer.setTabWidth(tabSize); // fInputGroup.getSourceViewer().setTabWidth(tabSize); // } else if (source.equals(fConsole) && property.equals(IConsoleConstants.P_CONSOLE_WIDTH)) { fOutputViewer.setConsoleWidth(fConsole.getConsoleWidth()); } } } @Override public void settingsChanged(final Set<String> groupIds) { final Map<String, Object> options = new HashMap<String, Object>(); UIAccess.getDisplay().syncExec(new Runnable() { @Override public void run() { handleSettingsChanged(groupIds, options); } }); } /** * @see ISettingsChangedHandler#handleSettingsChanged(Set, Map) */ protected void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) { if (fInputGroup != null && UIAccess.isOkToUse(fControl)) { fInputGroup.handleSettingsChanged(groupIds, options); } } protected void collectContextMenuPreferencePages(final List<String> pageIds) { pageIds.add("de.walware.statet.nico.preferencePages.Console"); //$NON-NLS-1$ } }