blob: 4ee16d00197ab609084afa526f43605c3f28e932 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2014 Tilera Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* William R. Swanson (Tilera Corporation)
* Marc Dumais (Ericsson) - bug 436095
* Marc Dumais (Ericsson) - bug 453227
*******************************************************************************/
// Package declaration
package org.eclipse.cdt.visualizer.ui;
// Java classes
import java.util.List;
import org.eclipse.cdt.debug.internal.ui.actions.OpenNewViewAction;
import org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils;
// Custom classes
import org.eclipse.cdt.visualizer.ui.events.IVisualizerViewerListener;
import org.eclipse.cdt.visualizer.ui.events.VisualizerViewerEvent;
import org.eclipse.cdt.visualizer.ui.util.SelectionProviderAdapter;
import org.eclipse.cdt.visualizer.ui.util.SelectionUtils;
import org.eclipse.cdt.visualizer.ui.util.WorkbenchSelectionAdapter;
// SWT/JFace classes
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.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
// Eclipse/CDT classes
import org.eclipse.ui.part.ViewPart;
// ----------------------------------------------------------------------------
// VisualizerView
// ----------------------------------------------------------------------------
/**
* CDT Visualizer View class.
*
* This is the default implementation of the Visualizer View.
* It can also serve as a base class for custom visualizer views.
*
* The Visualizer View is a simple container with a toolbar,
* which presents an instance of an IVisualizerViewer,
* and mediates passing of selections to and from the viewer.
*
* The intent of the VisualizerView class is to encapsulate the
* standard Eclipse workbench view support, so the viewer does
* not have to worry about such things.
*/
public class VisualizerView extends ViewPart implements IVisualizerViewerListener, ISelectionChangedListener {
// --- members ---
/** Whether view has been initialized */
protected boolean m_initialized = false;
/** Parent control of view. */
protected Composite m_parentControl = null;
/** Contained IVisualizerViewer control. */
protected IVisualizerViewer m_viewer = null;
/** Selection change event manager */
protected WorkbenchSelectionAdapter m_workbenchSelectionAdapter = null;
/** Context menu manager. */
protected MenuManager m_contextMenuManager = null;
/** Last context menu display location. */
protected Point m_contextMenuLocation = null;
/** Open New View action */
private OpenNewViewAction m_openNewViewAction = null;
// --- constructors/destructors ---
/** Constructor */
public VisualizerView() {
super();
m_openNewViewAction = new OpenNewViewAction();
m_openNewViewAction.init(this);
}
/** Dispose method */
@Override
public void dispose() {
super.dispose();
setViewer(null);
disposeSelectionHandling();
}
// --- accessors ---
/** Returns whether view has been initialized. */
public boolean isInitialized() {
return m_initialized;
}
/** Gets contained viewer control. */
public IVisualizerViewer getViewer() {
return m_viewer;
}
/** Sets contained viewer control. */
public void setViewer(IVisualizerViewer viewer) {
if (m_viewer != null) {
m_viewer.removeSelectionChangedListener(this);
m_viewer.removeVisualizerViewerListener(this);
}
m_viewer = viewer;
if (m_viewer != null) {
m_viewer.addVisualizerViewerListener(this);
m_viewer.addSelectionChangedListener(this);
updateUI();
populateMenu();
}
}
// --- ViewPart implementation ---
// IMPORTANT: a view may be loaded before the plugins, etc.
// that its content depends on, since Eclipse loads saved workbench "memento" state,
// including current perspective and view layout, before loading dependent plugins,
// and lazily loads plugins based on classes that get touched.
//
// Hence, a view class should invoke setInitialized(true) at the end
// of its createPartControl() method, and any methods that touch/repaint/update
// the view's controls, etc. should call isInitialized() to be sure
// these controls have been created.
/** Invoked when UI controls need to be created */
@Override
public void createPartControl(Composite parent) {
m_parentControl = parent;
// Reminder: Don't muck with the toolbar or toolbar menu here.
// (I.e. don't try to clean them out or set initial items.)
// VisualizerViewer's selection handling code
// allows the selected visualizer to set their content, and
// any fiddling you do here will only interfere with that.
// set up context menu support
initializeContextMenu();
// setup the view menu
initializeMenu();
// set up selection handling
initializeSelectionHandling();
// initialize viewer control
initializeViewer();
m_initialized = true;
}
/** Invoked when view should take the focus.
* Note: this can be invoked before the view is fully initialized
* (for example, when loading views from workspace memento information),
* in which case it should silently do nothing.
*/
@Override
public void setFocus() {
if (m_viewer != null)
m_viewer.setFocus();
}
// --- initialization support ---
/**
* Creates and returns VisualizerViewer control.
* Intended to be overridden by derived types.
*/
protected IVisualizerViewer createViewer(Composite parent) {
return (m_viewer != null) ? m_viewer : new VisualizerViewer(this, parent);
}
/**
* Invoked by createPartControl() method when view instance is created.
* Intended to be overridden by derived classes.
*/
protected void initializeViewer() {
IVisualizerViewer viewer = createViewer(m_parentControl);
setViewer(viewer);
}
// --- tab name management ---
/** Sets displayed tab name and description for this view. */
public void setTabName(String displayName) {
setPartName(displayName);
}
/** Sets displayed tab name and description for this view. */
public void setTabDescription(String description) {
setTitleToolTip(description);
}
// --- selection handling ---
/** Initializes selection handling for this view. */
protected void initializeSelectionHandling() {
// create workbench selection change adapter,
// to hook us into the workbench selection event mechanism
m_workbenchSelectionAdapter = new WorkbenchSelectionAdapter(this);
m_workbenchSelectionAdapter.addSelectionChangedListener(this);
}
/** Disposes selection handling for this view. */
protected void disposeSelectionHandling() {
if (m_workbenchSelectionAdapter != null) {
m_workbenchSelectionAdapter.dispose();
m_workbenchSelectionAdapter = null;
}
}
/** Gets current workbench selection. */
public ISelection getWorkbenchSelection() {
return m_workbenchSelectionAdapter.getSelection();
}
/** Sets current workbench selection, and raises selection changed event. */
public void setWorkbenchSelection(ISelection selection) {
m_workbenchSelectionAdapter.setSelection(this, selection);
}
/** Sets current workbench selection, and raises selection changed event. */
public void setWorkbenchSelection(List<?> selection) {
ISelection iselection = SelectionUtils.toSelection(selection);
m_workbenchSelectionAdapter.setSelection(this, iselection);
}
// --- ISelectionChangedListener implementation ---
/** Invoked by WorkbenchSelectionAdapter when selection changes,
* and by viewer when visualizer selection changes.
*/
@Override
public void selectionChanged(SelectionChangedEvent event) {
Object source = event.getSource();
if (source instanceof SelectionProviderAdapter) {
source = ((SelectionProviderAdapter) source).getActualSource();
}
// if the source is the current VisualizerViewer,
// it's a user selection in the viewer, so we want to pass
// the selection change on to the workbench
if (source == m_viewer) {
// tell viewer about workbench selection
ISelection selection = event.getSelection();
setWorkbenchSelection(selection);
// update toolbar/menu to reflect changed selection
updateUI();
}
// if the source is this view, it's an echo of a workbench
// event we sent out, so ignore it.
else if (source == this) {
// Do nothing.
}
// if the source is another instance of VisualizerView
// it's a selection in another (cloned) view. The
// workbench selection has or will be updated by the
// instance of the view where the selection originated,
// so no need to do anything
else if (source.getClass() == VisualizerView.class) {
// Do nothing.
}
// else this is a selection change from some other view
// in the workbench, which we should pass down to the viewer
else {
ISelection selection = event.getSelection();
workbenchSelectionChanged(selection);
// update toolbar/menu to reflect changed selection
updateUI();
}
}
/**
* Invoked from selectionChanged() when workbench's selection changes,
* but only if the selection change did not come from this view.
*/
public void workbenchSelectionChanged(ISelection selection) {
if (m_viewer != null) {
m_viewer.workbenchSelectionChanged(selection);
}
}
// --- IVisulizerViewerListener implementation ---
/** Invoked when visualizer in view has changed. */
@Override
public void visualizerEvent(IVisualizerViewer source, VisualizerViewerEvent event) {
switch (event.getType()) {
case VisualizerViewerEvent.VISUALIZER_CHANGED:
updateUI();
break;
case VisualizerViewerEvent.VISUALIZER_CONTEXT_MENU:
showContextMenu(event.x, event.y);
}
}
// --- update methods ---
/** Updates tab name, toolbar, etc. from viewer. */
public void updateUI() {
// Update tab name/tooltip
// TODO: internationalize these default strings
String name = "Visualizer View";
String description = "Displays visualizations of launches.";
if (m_viewer != null) {
name = m_viewer.getVisualizerDisplayName();
description = m_viewer.getVisualizerDescription();
}
setTabName(name);
// add secondary id to tab name, if the view is a clone
PinCloneUtils.setPartTitle(this);
setTabDescription(description);
// Update toolbar & toolbar menu
if (m_viewer != null) {
IActionBars actionBars = getViewSite().getActionBars();
// Allow presentation to set the displayed toolbar content, if any
IToolBarManager toolBarManager = actionBars.getToolBarManager();
toolBarManager.removeAll();
m_viewer.populateToolBar(toolBarManager);
// Add the "open new view" button on the Visualizer toolbar,
// after any viewer-specific buttons.
toolBarManager.add(m_openNewViewAction);
toolBarManager.update(true);
// Note: when context menu is invoked,
// the populateContextMenu() method is called by the view,
// which in turn delegates to the current visualizer
// to populate the context menu.
// Note2: when view menu is invoked,
// the populateMenu() method is called by the view,
// which in turn delegates to the current visualizer
// to populate the view menu.
// Propagate the changes
actionBars.updateActionBars();
}
}
// --- view menu support ---
/** Utility method that returns the menu manager for the view menu
* @since 1.2*/
protected IMenuManager getViewMenuManager() {
IActionBars actionBars = getViewSite().getActionBars();
return actionBars.getMenuManager();
}
/** Initialize the view menu
* @since 1.2*/
protected void initializeMenu() {
IMenuManager menuManager = getViewMenuManager();
menuManager.addMenuListener(new IMenuListener2() {
@Override
public void menuAboutToShow(IMenuManager m) {
viewMenuShow(m);
}
@Override
public void menuAboutToHide(IMenuManager m) {
viewMenuHide(m);
}
});
}
/** Invoked when the viewer is set to do an initial populating of the view
* menu. Without this, the view menu would not appear.
* @since 1.2*/
protected void populateMenu() {
IMenuManager menuManager = getViewMenuManager();
viewMenuShow(menuManager);
}
/** Invoked when view menu is about to be shown.
* @since 1.2*/
protected void viewMenuShow(IMenuManager m) {
m.removeAll();
m_viewer.populateMenu(m);
m.update();
}
/** Invoked when view menu is about to be hidden.
* @since 1.2*/
protected void viewMenuHide(IMenuManager m) {
}
// --- context menu support ---
/** Sets up context menu support. */
protected void initializeContextMenu() {
m_contextMenuManager = new MenuManager();
m_contextMenuManager.addMenuListener(new IMenuListener2() {
@Override
public void menuAboutToShow(IMenuManager m) {
VisualizerView.this.contextMenuShow(m);
}
@Override
public void menuAboutToHide(IMenuManager m) {
VisualizerView.this.contextMenuHide(m);
}
});
// We associate the view's context menu with the parent control.
// Viewer has the option of calling showContextMenu()
// to display the view's context menu.
Menu menu = m_contextMenuManager.createContextMenu(m_parentControl);
m_parentControl.setMenu(menu);
}
/** Invoked when context menu is about to be shown. */
protected void contextMenuShow(IMenuManager m) {
m.removeAll();
m_viewer.populateContextMenu(m);
m.update();
}
/** Invoked when context menu is about to be hidden. */
protected void contextMenuHide(IMenuManager m) {
}
/** Shows view's context menu at specified position. */
public void showContextMenu(int x, int y) {
Menu menu = m_parentControl.getMenu();
if (menu != null) {
menu.setLocation(x, y);
// capture context menu location in relative coordinates
m_contextMenuLocation = m_parentControl.toControl(x, y);
// Note: showing menu implicitly invokes populateContextMenu()
// to populate context menu items.
menu.setVisible(true);
// Make sure we have the focus now
// so we'll still have it when the menu goes away,
// and user doesn't have to click twice.
setFocus();
}
}
/** Gets context menu location. */
public Point getContextMenuLocation() {
// Just asking the menu for its own location doesn't work,
// so we have to capture it above and return it here.
return m_contextMenuLocation;
}
}