/******************************************************************************* * Copyright (c) 2008, 2012 Wind River Systems, Inc. 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.debug.test; import java.util.ArrayList; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.viewers.model.provisional.ITreeModelViewer; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.contexts.AbstractDebugContextProvider; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; /** * Copied from org.eclipse.debug.internal.ui.views.launch.LaunchView class. * * This debug context provider emulates the Debug view debug context * provider behavior. */ @SuppressWarnings("restriction") public class TestDebugContextProvider extends AbstractDebugContextProvider implements IModelChangedListener, ISelectionChangedListener{ private IWorkbenchWindow fWindow = null; private ISelection fContext = null; private ITreeModelViewer fViewer = null; private Visitor fVisitor = new Visitor(); class Visitor implements IModelDeltaVisitor { public boolean visit(IModelDelta delta, int depth) { if ((delta.getFlags() & (IModelDelta.STATE | IModelDelta.CONTENT)) > 0) { // state and/or content change if ((delta.getFlags() & IModelDelta.SELECT) == 0) { // no select flag if ((delta.getFlags() & IModelDelta.CONTENT) > 0) { // content has changed without select >> possible re-activation possibleChange(getViewerTreePath(delta), DebugContextEvent.ACTIVATED); } else if ((delta.getFlags() & IModelDelta.STATE) > 0) { // state has changed without select >> possible state change of active context possibleChange(getViewerTreePath(delta), DebugContextEvent.STATE); } } } return true; } } /** * Returns a tree path for the node, *not* including the root element. * * @param node * model delta * @return corresponding tree path */ private TreePath getViewerTreePath(IModelDelta node) { ArrayList<Object> list = new ArrayList<Object>(); IModelDelta parentDelta = node.getParentDelta(); while (parentDelta != null) { list.add(0, node.getElement()); node = parentDelta; parentDelta = node.getParentDelta(); } return new TreePath(list.toArray()); } public TestDebugContextProvider(ITreeModelViewer viewer) { super(null); fViewer = viewer; fViewer.addModelChangedListener(this); fViewer.addSelectionChangedListener(this); fWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (fWindow != null) { DebugUITools.getDebugContextManager().getContextService(fWindow).addDebugContextProvider(this); } } protected void dispose() { if (fWindow != null) { DebugUITools.getDebugContextManager().getContextService(fWindow).removeDebugContextProvider(this); } fContext = null; fViewer.removeModelChangedListener(this); fViewer.removeSelectionChangedListener(this); } /* (non-Javadoc) * @see org.eclipse.debug.ui.contexts.IDebugContextProvider#getActiveContext() */ public synchronized ISelection getActiveContext() { return fContext; } protected void activate(ISelection selection) { synchronized (this) { fContext = selection; } fire(new DebugContextEvent(this, selection, DebugContextEvent.ACTIVATED)); } protected void possibleChange(TreePath element, int type) { DebugContextEvent event = null; synchronized (this) { if (fContext instanceof ITreeSelection) { ITreeSelection ss = (ITreeSelection) fContext; if (ss.size() == 1) { TreePath current = ss.getPaths()[0]; if (current.startsWith(element, null)) { if (current.getSegmentCount() == element.getSegmentCount()) { event = new DebugContextEvent(this, fContext, type); } else { // if parent of the currently selected element // changes, issue event to update STATE only event = new DebugContextEvent(this, fContext, DebugContextEvent.STATE); } } } } } if (event == null) { return; } if (Display.getDefault().getThread() == Thread.currentThread()) { fire(event); } else { final DebugContextEvent finalEvent = event; Display.getDefault().asyncExec(new Runnable() { public void run() { // verify selection is still the same context since job was scheduled synchronized (TestDebugContextProvider.this) { if (fContext instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) fContext; Object changed = ((IStructuredSelection)finalEvent.getContext()).getFirstElement(); if (!(ss.size() == 1 && ss.getFirstElement().equals(changed))) { return; } } } fire(finalEvent); } }); } } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta) */ public void modelChanged(IModelDelta delta, IModelProxy proxy) { delta.accept(fVisitor); } public void selectionChanged(SelectionChangedEvent event) { activate(event.getSelection()); } }