blob: 2ba972ccfb20335f3a97ba95c1391fb79fea141f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.debug.internal.ui.views.variables;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages;
import org.eclipse.debug.internal.ui.views.IRemoteTreeViewerUpdateListener;
import org.eclipse.debug.internal.ui.views.RemoteTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.progress.UIJob;
/**
* Variables viewer. As the user steps through code, this
* we ensure that newly added varibles are visible.
*/
public class VariablesViewer extends RemoteTreeViewer {
private ArrayList fUpdateListeners = new ArrayList();
private StateRestorationJob fStateRestorationJob = new StateRestorationJob(DebugUIViewsMessages.RemoteTreeViewer_0);
private VariablesView fView = null;
private class StateRestorationJob extends UIJob {
public StateRestorationJob(String name) {
super(name);
setSystem(true);
}
/* (non-Javadoc)
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
*/
public IStatus runInUIThread(IProgressMonitor monitor) {
restoreExpansionState();
return Status.OK_STATUS;
}
}
/**
* Constructor for VariablesViewer.
* @param parent
* @param style
* @param view containing view, or <code>null</code> if none
*/
public VariablesViewer(Composite parent, int style, VariablesView view) {
super(parent, style);
fView = view;
}
/**
* @see AbstractTreeViewer#newItem(Widget, int, int)
*/
protected Item newItem(Widget parent, int style, int index) {
Item item = super.newItem(parent, style, index);
if (index != -1 && getSelection(getControl()).length == 0) {
//ignore the dummy items
showItem(item);
}
return item;
}
/**
* @see org.eclipse.jface.viewers.AbstractTreeViewer#setExpandedElements(Object[])
*/
public void setExpandedElements(Object[] elements) {
getControl().setRedraw(false);
super.setExpandedElements(elements);
getControl().setRedraw(true);
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.views.RemoteTreeViewer#runDeferredUpdates()
*/
protected void runDeferredUpdates() {
super.runDeferredUpdates();
fStateRestorationJob.schedule();
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.AbstractTreeViewer#collapseAll()
*/
public void collapseAll() {
//see https://bugs.eclipse.org/bugs/show_bug.cgi?id=39449
if (getRoot() != null) {
super.collapseAll();
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.views.RemoteTreeViewer#restoreExpansionState()
*/
protected synchronized void restoreExpansionState() {
cancelJobs();
for (Iterator i = fUpdateListeners.iterator(); i.hasNext();) {
IRemoteTreeViewerUpdateListener listener = (IRemoteTreeViewerUpdateListener) i.next();
listener.treeUpdated();
}
}
public void addUpdateListener(IRemoteTreeViewerUpdateListener listener) {
fUpdateListeners.add(listener);
}
public void removeUpdateListener(IRemoteTreeViewerUpdateListener listener) {
fUpdateListeners.remove(listener);
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.views.RemoteTreeViewer#replace(java.lang.Object, java.lang.Object[], int)
*/
public synchronized void replace(Object parent, Object[] children, int offset) {
if (fView != null) {
if (children.length == 1 && children[0] instanceof DebugException) {
IStatus status = ((DebugException)children[0]).getStatus();
if (status != null) {
String message = status.getMessage();
if (message != null) {
fView.showMessage(message);
}
}
return;
}
fView.showViewer();
}
super.replace(parent, children, offset);
}
public boolean expandPath(IPath path) {
String[] strings = path.segments();
Item[] children = getChildren(getControl());
return internalExpandPath(strings, 0, children);
}
protected boolean internalExpandPath(String[] segments, int index, Item[] children) {
try {
String pathSegment = segments[index];
for (int j = 0; j < children.length; j++) {
Item child = children[j];
Object data = child.getData();
String name = null;
if (data instanceof IVariable) {
IVariable var = (IVariable) data;
name = var.getName();
} else if (data instanceof IRegisterGroup) {
IRegisterGroup registerGroup = (IRegisterGroup) data;
name = registerGroup.getName();
}
if (name != null && pathSegment.equals(name)) {
ITreeContentProvider provider = (ITreeContentProvider) getContentProvider();
provider.getChildren(child.getData());
setExpanded(child, true);
index++;
if (index < segments.length) {
Item[] newChildren = getChildren(child);
return internalExpandPath(segments, index, newChildren);
}
return true;
}
}
} catch (DebugException e) {
}
return false;
}
}