1 /*******************************************************************************
2  * Copyright (c) 2000, 2018 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     vogella GmbH - Bug 287303 - [patch] Add Word Wrap action to Console View
14  *     Andrey Loskutov <loskutov@gmx.de> - Bug 466789
15  *******************************************************************************/
16 package org.eclipse.ui.internal.console;
17 
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 
23 import org.eclipse.core.runtime.ISafeRunnable;
24 import org.eclipse.core.runtime.ListenerList;
25 import org.eclipse.core.runtime.SafeRunner;
26 import org.eclipse.jface.action.ActionContributionItem;
27 import org.eclipse.jface.action.IAction;
28 import org.eclipse.jface.action.IToolBarManager;
29 import org.eclipse.jface.action.Separator;
30 import org.eclipse.jface.action.ToolBarManager;
31 import org.eclipse.jface.resource.ImageDescriptor;
32 import org.eclipse.jface.util.IPropertyChangeListener;
33 import org.eclipse.jface.util.PropertyChangeEvent;
34 import org.eclipse.jface.viewers.IBasicPropertyConstants;
35 import org.eclipse.swt.custom.StyledText;
36 import org.eclipse.swt.events.MouseAdapter;
37 import org.eclipse.swt.events.MouseEvent;
38 import org.eclipse.swt.graphics.Point;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.eclipse.swt.widgets.Event;
42 import org.eclipse.swt.widgets.ToolBar;
43 import org.eclipse.swt.widgets.ToolItem;
44 import org.eclipse.ui.IPartListener2;
45 import org.eclipse.ui.IViewReference;
46 import org.eclipse.ui.IViewSite;
47 import org.eclipse.ui.IWorkbenchPart;
48 import org.eclipse.ui.IWorkbenchPartReference;
49 import org.eclipse.ui.PlatformUI;
50 import org.eclipse.ui.console.AbstractConsole;
51 import org.eclipse.ui.console.ConsolePlugin;
52 import org.eclipse.ui.console.IConsole;
53 import org.eclipse.ui.console.IConsoleConstants;
54 import org.eclipse.ui.console.IConsoleListener;
55 import org.eclipse.ui.console.IConsoleManager;
56 import org.eclipse.ui.console.IConsolePageParticipant;
57 import org.eclipse.ui.console.IConsoleView;
58 import org.eclipse.ui.console.TextConsolePage;
59 import org.eclipse.ui.console.TextConsoleViewer;
60 import org.eclipse.ui.contexts.IContextActivation;
61 import org.eclipse.ui.contexts.IContextService;
62 import org.eclipse.ui.part.IPage;
63 import org.eclipse.ui.part.IPageBookViewPage;
64 import org.eclipse.ui.part.MessagePage;
65 import org.eclipse.ui.part.PageBook;
66 import org.eclipse.ui.part.PageBookView;
67 import org.eclipse.ui.part.PageSwitcher;
68 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
69 
70 /**
71  * Page book console view.
72  *
73  * @since 3.0
74  */
75 public class ConsoleView extends PageBookView implements IConsoleView, IConsoleListener, IPropertyChangeListener, IPartListener2 {
76 
77 	/**
78 	 * Whether this console is pinned.
79 	 */
80 	private boolean fPinned = false;
81 
82 	/**
83 	 * Stack of consoles in MRU order
84 	 */
85 	private List<IConsole> fStack = new ArrayList<>();
86 
87 	/**
88 	 * The console being displayed, or <code>null</code> if none
89 	 */
90 	private IConsole fActiveConsole = null;
91 
92 	/**
93 	 * Map of consoles to dummy console parts (used to close pages)
94 	 */
95 	private Map<IConsole, ConsoleWorkbenchPart> fConsoleToPart;
96 
97 	/**
98 	 * Map of consoles to array of page participants
99 	 */
100 	private Map<IConsole, ListenerList<IConsolePageParticipant>> fConsoleToPageParticipants;
101 
102 	/**
103 	 * Map of parts to consoles
104 	 */
105 	private Map<ConsoleWorkbenchPart, IConsole> fPartToConsole;
106 
107 	/**
108 	 * Whether this view is active
109 	 */
110 	private boolean fActive = false;
111 
112 	/**
113 	 * 'In Console View' context
114 	 */
115 	private IContextActivation fActivatedContext;
116 
117 	// actions
118 	private PinConsoleAction fPinAction = null;
119 	private ConsoleDropDownAction fDisplayConsoleAction = null;
120 
121 	private OpenConsoleAction fOpenConsoleAction = null;
122 
123 	private boolean fScrollLock;
124 	private boolean fWordWrap;
125 
isAvailable()126 	private boolean isAvailable() {
127 		return getPageBook() != null && !getPageBook().isDisposed();
128 	}
129 
130 	@Override
propertyChange(PropertyChangeEvent event)131 	public void propertyChange(PropertyChangeEvent event) {
132 		Object source = event.getSource();
133 		if (source instanceof IConsole && event.getProperty().equals(IBasicPropertyConstants.P_TEXT)) {
134 			if (source.equals(getConsole())) {
135 				updateTitle();
136 			}
137 		}
138 
139 	}
140 
141 	@Override
partClosed(IWorkbenchPart part)142 	public void partClosed(IWorkbenchPart part) {
143 		super.partClosed(part);
144 		fPinAction.update();
145 	}
146 
147 	@Override
getConsole()148 	public IConsole getConsole() {
149 		return fActiveConsole;
150 	}
151 
152 	@Override
showPageRec(PageRec pageRec)153 	protected void showPageRec(PageRec pageRec) {
154 		// don't show the page when pinned, unless this is the first console to be added
155 		// or its the default page
156 		if (fActiveConsole != null && pageRec.page != getDefaultPage() && fPinned && fConsoleToPart.size() > 1) {
157 			IConsole console = fPartToConsole.get(pageRec.part);
158 			if (!fStack.contains(console)) {
159 				fStack.add(console);
160 			}
161 			return;
162 		}
163 
164 		IConsole recConsole = fPartToConsole.get(pageRec.part);
165 		if (recConsole!=null && recConsole.equals(fActiveConsole)) {
166 			return;
167 		}
168 
169 		super.showPageRec(pageRec);
170 
171 		if (fActiveConsole != recConsole) {
172 			if (fActive && fActiveConsole != null) {
173 				deactivateParticipants(fActiveConsole);
174 			}
175 			if (recConsole != null) {
176 				activateParticipants(recConsole);
177 			}
178 		}
179 		fActiveConsole = recConsole;
180 		// bring active console on top of stack
181 		if (fActiveConsole != null && !fStack.isEmpty() && !fActiveConsole.equals(fStack.get(0))) {
182 			fStack.remove(fActiveConsole);
183 			fStack.add(0, fActiveConsole);
184 		}
185 		updateTitle();
186 		updateHelp();
187 		// update console actions
188 		if (fPinAction != null) {
189 			fPinAction.update();
190 		}
191 		IPage page = getCurrentPage();
192 		if (page instanceof IOConsolePage) {
193 			((IOConsolePage) page).setWordWrap(fWordWrap);
194 		}
195 		/*
196 		 * Bug 268608: cannot invoke find/replace after opening console
197 		 *
198 		 * Global actions of TextConsolePage must be updated here,
199 		 * but they are only updated on a selection change.
200 		 */
201 		if (page instanceof TextConsolePage) {
202 			TextConsoleViewer viewer = ((TextConsolePage) page).getViewer();
203 			viewer.setSelection(viewer.getSelection());
204 		}
205 	}
206 
207 	/**
208 	 * Activates the participants for the given console, if any.
209 	 *
210 	 * @param console the console
211 	 */
activateParticipants(IConsole console)212 	private void activateParticipants(IConsole console) {
213 		// activate
214 		if (console != null && fActive) {
215 			final ListenerList<IConsolePageParticipant> listeners = getParticipants(console);
216 			if (listeners != null) {
217 				for (IConsolePageParticipant iConsolePageParticipant : listeners) {
218 					final IConsolePageParticipant participant = iConsolePageParticipant;
219 					SafeRunner.run(new ISafeRunnable() {
220 						@Override
221 						public void run() throws Exception {
222 							participant.activated();
223 						}
224 						@Override
225 						public void handleException(Throwable exception) {
226 							ConsolePlugin.log(exception);
227 							listeners.remove(participant);
228 						}
229 					});
230 				}
231 			}
232 		}
233 	}
234 
235 	/**
236 	 * Returns a stack of consoles in the view in MRU order.
237 	 *
238 	 * @return a stack of consoles in the view in MRU order
239 	 */
getConsoleStack()240 	protected List<IConsole> getConsoleStack() {
241 		return fStack;
242 	}
243 
244 	/**
245 	 * Updates the view title based on the active console
246 	 */
updateTitle()247 	protected void updateTitle() {
248 		IConsole console = getConsole();
249 		if (console == null) {
250 			setContentDescription(ConsoleMessages.ConsoleView_0);
251 		} else {
252 			String newName = console.getName();
253 			String oldName = getContentDescription();
254 			if (newName!=null && !(newName.equals(oldName))) {
255 				setContentDescription(console.getName());
256 			}
257 		}
258 	}
259 
updateHelp()260 	protected void updateHelp() {
261 		IConsole console = getConsole();
262 		String helpContextId = null;
263 		if (console instanceof AbstractConsole) {
264 			AbstractConsole abs = (AbstractConsole) console;
265 			helpContextId = abs.getHelpContextId();
266 		}
267 		if (helpContextId == null) {
268 			helpContextId = IConsoleHelpContextIds.CONSOLE_VIEW;
269 		}
270 		PlatformUI.getWorkbench().getHelpSystem().setHelp(getPageBook().getParent(), helpContextId);
271 	}
272 
273 	@Override
doDestroyPage(IWorkbenchPart part, PageRec pageRecord)274 	protected void doDestroyPage(IWorkbenchPart part, PageRec pageRecord) {
275 		IConsole console = fPartToConsole.get(part);
276 
277 		// dispose page participants
278 		ListenerList<IConsolePageParticipant> listeners = fConsoleToPageParticipants.remove(console);
279 		if (listeners != null) {
280 			for (IConsolePageParticipant iConsolePageParticipant : listeners) {
281 				final IConsolePageParticipant participant = iConsolePageParticipant;
282 				SafeRunner.run(new ISafeRunnable() {
283 					@Override
284 					public void run() throws Exception {
285 						participant.dispose();
286 					}
287 					@Override
288 					public void handleException(Throwable exception) {
289 						ConsolePlugin.log(exception);
290 					}
291 				});
292 			}
293 		}
294 
295 		IPage page = pageRecord.page;
296 		page.dispose();
297 		pageRecord.dispose();
298 		console.removePropertyChangeListener(this);
299 
300 		// empty cross-reference cache
301 		fPartToConsole.remove(part);
302 		fConsoleToPart.remove(console);
303 		if (fPartToConsole.isEmpty()) {
304 			fActiveConsole = null;
305 		}
306 
307 		// update console actions
308 		fPinAction.update();
309 	}
310 
311 	/**
312 	 * Returns the page participants registered for the given console, or
313 	 * <code>null</code>
314 	 *
315 	 * @param console the console
316 	 * @return registered page participants or <code>null</code>
317 	 */
getParticipants(IConsole console)318 	private ListenerList<IConsolePageParticipant> getParticipants(IConsole console) {
319 		return fConsoleToPageParticipants.get(console);
320 	}
321 
322 	@Override
doCreatePage(IWorkbenchPart dummyPart)323 	protected PageRec doCreatePage(IWorkbenchPart dummyPart) {
324 		ConsoleWorkbenchPart part = (ConsoleWorkbenchPart)dummyPart;
325 		final IConsole console = part.getConsole();
326 		final IPageBookViewPage page = console.createPage(this);
327 		initPage(page);
328 		page.createControl(getPageBook());
329 		console.addPropertyChangeListener(this);
330 
331 		// initialize page participants
332 		IConsolePageParticipant[] consoleParticipants = ((ConsoleManager)getConsoleManager()).getPageParticipants(console);
333 		final ListenerList<IConsolePageParticipant> participants = new ListenerList<>();
334 		for (IConsolePageParticipant consoleParticipant : consoleParticipants) {
335 			participants.add(consoleParticipant);
336 		}
337 		fConsoleToPageParticipants.put(console, participants);
338 		for (IConsolePageParticipant iConsolePageParticipant : participants) {
339 			final IConsolePageParticipant participant = iConsolePageParticipant;
340 			SafeRunner.run(new ISafeRunnable() {
341 				@Override
342 				public void run() throws Exception {
343 					participant.init(page, console);
344 				}
345 				@Override
346 				public void handleException(Throwable exception) {
347 					ConsolePlugin.log(exception);
348 					participants.remove(participant);
349 				}
350 			});
351 		}
352 
353 		PageRec rec = new PageRec(dummyPart, page);
354 		return rec;
355 	}
356 
357 	@Override
isImportant(IWorkbenchPart part)358 	protected boolean isImportant(IWorkbenchPart part) {
359 		return part instanceof ConsoleWorkbenchPart;
360 	}
361 
362 	@Override
dispose()363 	public void dispose() {
364 		IViewSite site = getViewSite();
365 		if(site != null) {
366 			site.getPage().removePartListener((IPartListener2)this);
367 		}
368 		super.dispose();
369 		ConsoleManager consoleManager = (ConsoleManager) ConsolePlugin.getDefault().getConsoleManager();
370 		consoleManager.removeConsoleListener(this);
371 		consoleManager.unregisterConsoleView(this);
372 		if (fDisplayConsoleAction != null) {
373 			fDisplayConsoleAction.dispose();
374 			fDisplayConsoleAction = null;
375 		}
376 		if (fOpenConsoleAction != null) {
377 			fOpenConsoleAction.dispose();
378 			fOpenConsoleAction = null;
379 		}
380 	}
381 
382 	/**
383 	 * Returns the console manager.
384 	 *
385 	 * @return the console manager
386 	 */
getConsoleManager()387 	private IConsoleManager getConsoleManager() {
388 		return ConsolePlugin.getDefault().getConsoleManager();
389 	}
390 
391 	@Override
createDefaultPage(PageBook book)392 	protected IPage createDefaultPage(PageBook book) {
393 		MessagePage page = new MessagePage();
394 		page.createControl(getPageBook());
395 		initPage(page);
396 		return page;
397 	}
398 
399 	@Override
consolesAdded(final IConsole[] consoles)400 	public void consolesAdded(final IConsole[] consoles) {
401 		if (isAvailable()) {
402 			Runnable r = () -> {
403 				for (IConsole console : consoles) {
404 					if (isAvailable()) {
405 						// ensure it's still registered since this is done asynchronously
406 						IConsole[] allConsoles = getConsoleManager().getConsoles();
407 						for (IConsole registered : allConsoles) {
408 							if (registered.equals(console)) {
409 								ConsoleWorkbenchPart part = new ConsoleWorkbenchPart(console, getSite());
410 								fConsoleToPart.put(console, part);
411 								fPartToConsole.put(part, console);
412 								partActivated(part);
413 								break;
414 							}
415 						}
416 					}
417 				}
418 			};
419 			asyncExec(r);
420 		}
421 	}
422 
423 	@Override
consolesRemoved(final IConsole[] consoles)424 	public void consolesRemoved(final IConsole[] consoles) {
425 		if (isAvailable()) {
426 			Runnable r = () -> {
427 				for (IConsole console : consoles) {
428 					if (isAvailable()) {
429 						fStack.remove(console);
430 						ConsoleWorkbenchPart part = fConsoleToPart.get(console);
431 						if (part != null) {
432 							partClosed(part);
433 						}
434 						if (getConsole() == null) {
435 							IConsole[] available = getConsoleManager().getConsoles();
436 							if (available.length > 0) {
437 								display(available[available.length - 1]);
438 							}
439 						}
440 					}
441 				}
442 			};
443 			asyncExec(r);
444 		}
445 	}
446 
447 	/**
448 	 * Constructs a console view
449 	 */
ConsoleView()450 	public ConsoleView() {
451 		super();
452 		fConsoleToPart = new HashMap<>();
453 		fPartToConsole = new HashMap<>();
454 		fConsoleToPageParticipants = new HashMap<>();
455 
456 		ConsoleManager consoleManager = (ConsoleManager) ConsolePlugin.getDefault().getConsoleManager();
457 		consoleManager.registerConsoleView(this);
458 	}
459 
createActions()460 	protected void createActions() {
461 		fPinAction = new PinConsoleAction(this);
462 		fDisplayConsoleAction = new ConsoleDropDownAction(this);
463 		ConsoleFactoryExtension[] extensions = ((ConsoleManager)ConsolePlugin.getDefault().getConsoleManager()).getConsoleFactoryExtensions();
464 		if (extensions.length > 0) {
465 			fOpenConsoleAction = new OpenConsoleAction();
466 		}
467 	}
468 
configureToolBar(IToolBarManager mgr)469 	protected void configureToolBar(IToolBarManager mgr) {
470 		mgr.add(new Separator(IConsoleConstants.LAUNCH_GROUP));
471 		mgr.add(new Separator(IConsoleConstants.OUTPUT_GROUP));
472 		mgr.add(new Separator("fixedGroup")); //$NON-NLS-1$
473 		mgr.add(fPinAction);
474 		mgr.add(fDisplayConsoleAction);
475 		if (fOpenConsoleAction != null) {
476 			mgr.add(fOpenConsoleAction);
477 			if (mgr instanceof ToolBarManager) {
478 				ToolBarManager tbm= (ToolBarManager) mgr;
479 				final ToolBar tb= tbm.getControl();
480 				tb.addMouseListener(new MouseAdapter() {
481 					@Override
482 					public void mouseDown(MouseEvent e) {
483 						ToolItem ti= tb.getItem(new Point(e.x, e.y));
484 						if (ti != null) {
485 							if (ti.getData() instanceof ActionContributionItem) {
486 								ActionContributionItem actionContributionItem= (ActionContributionItem) ti.getData();
487 								IAction action= actionContributionItem.getAction();
488 								if (action == fOpenConsoleAction) {
489 									Event event= new Event();
490 									event.widget= ti;
491 									event.x= e.x;
492 									event.y= e.y;
493 									action.runWithEvent(event);
494 								}
495 							}
496 						}
497 					}
498 				});
499 			}
500 		}
501 	}
502 
503 	@Override
display(IConsole console)504 	public void display(IConsole console) {
505 		if (fPinned && fActiveConsole != null) {
506 			return;
507 		}
508 		if (console.equals(fActiveConsole)) {
509 			return;
510 		}
511 		ConsoleWorkbenchPart part = fConsoleToPart.get(console);
512 		if (part != null) {
513 			partActivated(part);
514 			// Workaround for bug 345435: call activated for this to force PageBookView to
515 			// activate the new pages context
516 			if (fActive) {
517 				partActivated(this);
518 			}
519 		}
520 	}
521 
522 	@Override
setPinned(boolean pin)523 	public void setPinned(boolean pin) {
524 		fPinned = pin;
525 		if (fPinAction != null) {
526 			fPinAction.update();
527 		}
528 	}
529 
530 	@Override
isPinned()531 	public boolean isPinned() {
532 		return fPinned;
533 	}
534 
535 	@Override
getBootstrapPart()536 	protected IWorkbenchPart getBootstrapPart() {
537 		return null;
538 	}
539 
540 	/**
541 	 * Registers the given runnable with the display associated with this view's
542 	 * control, if any.
543 	 *
544 	 * @param r the runnable
545 	 * @see org.eclipse.swt.widgets.Display#asyncExec(java.lang.Runnable)
546 	 */
asyncExec(Runnable r)547 	public void asyncExec(Runnable r) {
548 		if (isAvailable()) {
549 			getPageBook().getDisplay().asyncExec(r);
550 		}
551 	}
552 
553 	/**
554 	 * Creates this view's underlying viewer and actions.
555 	 * Hooks a pop-up menu to the underlying viewer's control,
556 	 * as well as a key listener. When the delete key is pressed,
557 	 * the <code>REMOVE_ACTION</code> is invoked. Hooks help to
558 	 * this view. Subclasses must implement the following methods
559 	 * which are called in the following order when a view is
560 	 * created:<ul>
561 	 * <li><code>createViewer(Composite)</code> - the context
562 	 *   menu is hooked to the viewer's control.</li>
563 	 * <li><code>createActions()</code></li>
564 	 * <li><code>configureToolBar(IToolBarManager)</code></li>
565 	 * <li><code>getHelpContextId()</code></li>
566 	 * </ul>
567 	 * @see IWorkbenchPart#createPartControl(Composite)
568 	 */
569 	@Override
createPartControl(Composite parent)570 	public void createPartControl(Composite parent) {
571 		super.createPartControl(parent);
572 		createActions();
573 		IToolBarManager tbm= getViewSite().getActionBars().getToolBarManager();
574 		configureToolBar(tbm);
575 		updateForExistingConsoles();
576 		getViewSite().getActionBars().updateActionBars();
577 		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IConsoleHelpContextIds.CONSOLE_VIEW);
578 		getViewSite().getPage().addPartListener((IPartListener2)this);
579 		initPageSwitcher();
580 	}
581 
582 	/**
583 	 * Initialize the PageSwitcher.
584 	 */
initPageSwitcher()585 	private void initPageSwitcher() {
586 		new PageSwitcher(this) {
587 			@Override
588 			public void activatePage(Object page) {
589 				ShowConsoleAction.showConsole((IConsole) page, ConsoleView.this);
590 			}
591 
592 			@Override
593 			public ImageDescriptor getImageDescriptor(Object page) {
594 				return ((IConsole) page).getImageDescriptor();
595 			}
596 
597 			@Override
598 			public String getName(Object page) {
599 				return ((IConsole) page).getName();
600 			}
601 
602 			@Override
603 			public Object[] getPages() {
604 				return getConsoleManager().getConsoles();
605 			}
606 
607 			@Override
608 			public int getCurrentPageIndex() {
609 				IConsole currentConsole= getConsole();
610 				IConsole[] consoles= getConsoleManager().getConsoles();
611 				for (int i= 0; i < consoles.length; i++) {
612 					if (consoles[i].equals(currentConsole)) {
613 						return i;
614 					}
615 				}
616 				return super.getCurrentPageIndex();
617 			}
618 		};
619 	}
620 
621 	/**
622 	 * Initialize for existing consoles
623 	 */
updateForExistingConsoles()624 	private void updateForExistingConsoles() {
625 		IConsoleManager manager = getConsoleManager();
626 		// create pages for consoles
627 		IConsole[] consoles = manager.getConsoles();
628 		consolesAdded(consoles);
629 		// add as a listener
630 		manager.addConsoleListener(this);
631 	}
632 
633 	@Override
warnOfContentChange(IConsole console)634 	public void warnOfContentChange(IConsole console) {
635 		IWorkbenchPart part = fConsoleToPart.get(console);
636 		if (part != null) {
637 			IWorkbenchSiteProgressService service = part.getSite().getAdapter(IWorkbenchSiteProgressService.class);
638 			if (service != null) {
639 				service.warnOfContentChange();
640 			}
641 		}
642 	}
643 
644 	@SuppressWarnings("unchecked")
645 	@Override
getAdapter(Class<T> key)646 	public <T> T getAdapter(Class<T> key) {
647 		Object adpater = super.getAdapter(key);
648 		if (adpater == null) {
649 			IConsole console = getConsole();
650 			if (console != null) {
651 				ListenerList<IConsolePageParticipant> listeners = getParticipants(console);
652 				// an adapter can be asked for before the console participants are created
653 				if (listeners != null) {
654 					for (IConsolePageParticipant iConsolePageParticipant : listeners) {
655 						IConsolePageParticipant participant = iConsolePageParticipant;
656 						adpater = participant.getAdapter(key);
657 						if (adpater != null) {
658 							return (T) adpater;
659 						}
660 					}
661 				}
662 			}
663 		}
664 		return (T) adpater;
665 	}
666 
667 	@Override
partActivated(IWorkbenchPartReference partRef)668 	public void partActivated(IWorkbenchPartReference partRef) {
669 		if (isThisPart(partRef)) {
670 			fActive = true;
671 			IContextService contextService = getSite().getService(IContextService.class);
672 			if(contextService != null) {
673 				fActivatedContext = contextService.activateContext(IConsoleConstants.ID_CONSOLE_VIEW);
674 				activateParticipants(fActiveConsole);
675 			}
676 		}
677 	}
678 
679 	@Override
partBroughtToTop(IWorkbenchPartReference partRef)680 	public void partBroughtToTop(IWorkbenchPartReference partRef) {
681 	}
682 
683 	@Override
partClosed(IWorkbenchPartReference partRef)684 	public void partClosed(IWorkbenchPartReference partRef) {
685 	}
686 
687 	@Override
partDeactivated(IWorkbenchPartReference partRef)688 	public void partDeactivated(IWorkbenchPartReference partRef) {
689 		if (isThisPart(partRef)) {
690 			fActive = false;
691 			IContextService contextService = getSite().getService(IContextService.class);
692 			if(contextService != null) {
693 				contextService.deactivateContext(fActivatedContext);
694 				deactivateParticipants(fActiveConsole);
695 			}
696 		}
697 	}
698 
699 	/**
700 	 * Returns if the specified part reference is to this view part (if the part
701 	 * reference is the console view or not)
702 	 *
703 	 * @param partRef the workbench part reference
704 	 * @return true if the specified part reference is the console view
705 	 */
isThisPart(IWorkbenchPartReference partRef)706 	protected boolean isThisPart(IWorkbenchPartReference partRef) {
707 		if (partRef instanceof IViewReference) {
708 			IViewReference viewRef = (IViewReference) partRef;
709 			if (getViewSite() != null && viewRef.getId().equals(getViewSite().getId())) {
710 				String secId = viewRef.getSecondaryId();
711 				String mySec = null;
712 				if (getSite() instanceof IViewSite) {
713 					mySec = ((IViewSite)getSite()).getSecondaryId();
714 				}
715 				if (mySec == null) {
716 					return secId == null;
717 				}
718 				return mySec.equals(secId);
719 			}
720 		}
721 		return false;
722 	}
723 
724 	/**
725 	 * Deactivates participants for the given console, if any.
726 	 *
727 	 * @param console console to deactivate
728 	 */
deactivateParticipants(IConsole console)729 	private void deactivateParticipants(IConsole console) {
730 		// deactivate
731 		if (console != null) {
732 			final ListenerList<IConsolePageParticipant> listeners = getParticipants(console);
733 			if (listeners != null) {
734 				for (IConsolePageParticipant iConsolePageParticipant : listeners) {
735 					final IConsolePageParticipant participant = iConsolePageParticipant;
736 					SafeRunner.run(new ISafeRunnable() {
737 						@Override
738 						public void run() throws Exception {
739 							participant.deactivated();
740 						}
741 						@Override
742 						public void handleException(Throwable exception) {
743 							ConsolePlugin.log(exception);
744 							listeners.remove(participant);
745 						}
746 					});
747 				}
748 			}
749 		}
750 	}
751 
752 	@Override
partOpened(IWorkbenchPartReference partRef)753 	public void partOpened(IWorkbenchPartReference partRef) {
754 	}
755 
756 	@Override
partHidden(IWorkbenchPartReference partRef)757 	public void partHidden(IWorkbenchPartReference partRef) {
758 	}
759 
760 	@Override
partVisible(IWorkbenchPartReference partRef)761 	public void partVisible(IWorkbenchPartReference partRef) {
762 	}
763 
764 	@Override
partInputChanged(IWorkbenchPartReference partRef)765 	public void partInputChanged(IWorkbenchPartReference partRef) {
766 	}
767 
768 	@Override
setScrollLock(boolean scrollLock)769 	public void setScrollLock(boolean scrollLock) {
770 		fScrollLock = scrollLock;
771 
772 		IPage page = getCurrentPage();
773 		if (page instanceof IOConsolePage) {
774 			((IOConsolePage)page).setAutoScroll(!scrollLock);
775 		}
776 	}
777 
778 	@Override
getScrollLock()779 	public boolean getScrollLock() {
780 		return fScrollLock;
781 	}
782 
783 	@Override
setWordWrap(boolean wordWrap)784 	public void setWordWrap(boolean wordWrap) {
785 		fWordWrap = wordWrap;
786 
787 		IWorkbenchPart part = getSite().getPart();
788 		if (part instanceof PageBookView) {
789 			Control control = ((PageBookView) part).getCurrentPage().getControl();
790 			if (control instanceof StyledText) {
791 				((StyledText) control).setWordWrap(wordWrap);
792 			}
793 		}
794 	}
795 
796 	@Override
getWordWrap()797 	public boolean getWordWrap() {
798 		return fWordWrap;
799 	}
800 
801 	@Override
pin(IConsole console)802 	public void pin(IConsole console) {
803 		if (console == null) {
804 			setPinned(false);
805 		} else {
806 			if (isPinned()) {
807 				setPinned(false);
808 			}
809 			display(console);
810 			setPinned(true);
811 		}
812 	}
813 
814 	@Override
setAutoScrollLock(boolean scrollLock)815 	public void setAutoScrollLock(boolean scrollLock) {
816 		IPage page = getCurrentPage();
817 		if (page instanceof IOConsolePage) {
818 			((IOConsolePage) page).setAutoScroll(!scrollLock);
819 		}
820 
821 	}
822 
823 	@Override
getAutoScrollLock()824 	public boolean getAutoScrollLock() {
825 		IPage page = getCurrentPage();
826 		if (page instanceof IOConsolePage) {
827 			return !((IOConsolePage) page).isAutoScroll();
828 		}
829 		return fScrollLock;
830 	}
831 }
832