diff options
author | Darin Wright | 2006-04-24 19:52:23 +0000 |
---|---|---|
committer | Darin Wright | 2006-04-24 19:52:23 +0000 |
commit | 8ffc8b3b5b14b0d7ff98289a47560d2c8c07b6da (patch) | |
tree | 6751d71cac34b216fc4a7aeaf13f01b01410965b | |
parent | fee44c8cf8c1b95979a63e56d6e681e39b750b91 (diff) | |
download | eclipse.platform.debug-8ffc8b3b5b14b0d7ff98289a47560d2c8c07b6da.tar.gz eclipse.platform.debug-8ffc8b3b5b14b0d7ff98289a47560d2c8c07b6da.tar.xz eclipse.platform.debug-8ffc8b3b5b14b0d7ff98289a47560d2c8c07b6da.zip |
Bug 127025 - system thread filter loses selection/collapses on first invocation
Bug 136416 - Terminated threads appearing in debug view
10 files changed, 354 insertions, 274 deletions
diff --git a/org.eclipse.debug.ui/.options b/org.eclipse.debug.ui/.options index a2688151a..1f8123685 100644 --- a/org.eclipse.debug.ui/.options +++ b/org.eclipse.debug.ui/.options @@ -1,2 +1,3 @@ org.eclipse.debug.ui/debug = false -org.eclipse.debug.ui/debug/viewer_cache_debug = false +org.eclipse.debug.ui/debug/viewers/model = false +org.eclipse.debug.ui/debug/viewers/viewer = false diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPlugin.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPlugin.java index a9e96c900..23aef05e4 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPlugin.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPlugin.java @@ -151,13 +151,6 @@ public class DebugUIPlugin extends AbstractUIPlugin implements ILaunchListener { public static String ATTR_LAUNCHING_CONFIG_HANDLE= getUniqueIdentifier() + "launching_config_handle"; //$NON-NLS-1$ /** - * Flag indicating whether the debug UI is in trace - * mode. When in trace mode, extra debug information - * is produced. - */ - private boolean fTrace = false; - - /** * Singleton console document manager */ private ProcessConsoleManager fProcessConsoleManager = null; @@ -190,6 +183,8 @@ public class DebugUIPlugin extends AbstractUIPlugin implements ILaunchListener { */ private ServiceTracker fServiceTracker; private PackageAdmin fPackageAdminService; + + public static boolean DEBUG = false; /** * Dummy launch node representing a launch that is waiting @@ -216,17 +211,6 @@ public class DebugUIPlugin extends AbstractUIPlugin implements ILaunchListener { } /** - * Returns whether the debug UI plug-in is in trace - * mode. - * - * @return whether the debug UI plug-in is in trace - * mode - */ - public boolean isTraceMode() { - return fTrace; - } - - /** * Returns the bundle the given class originated from. * * @param clazz a class @@ -242,24 +226,18 @@ public class DebugUIPlugin extends AbstractUIPlugin implements ILaunchListener { } /** - * Logs the given message if in trace mode. - * - * @param String message to log - */ - public static void logTraceMessage(String message) { - if (getDefault().isTraceMode()) { - IStatus s = new Status(IStatus.WARNING, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, message, null); - getDefault().getLog().log(s); - } - } - - /** * Constructs the debug UI plugin */ public DebugUIPlugin() { super(); fgDebugUIPlugin= this; } + + public static void debug(String message) { + if (DEBUG) { + System.out.println(message); + } + } /** * Returns the singleton instance of the debug plugin. @@ -409,6 +387,8 @@ public class DebugUIPlugin extends AbstractUIPlugin implements ILaunchListener { public void start(BundleContext context) throws Exception { super.start(context); + DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.debug.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$ + // make sure the perspective manager is created // and be the first debug event listener fPerspectiveManager = new PerspectiveManager(); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java index 740531dd5..c37644d30 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java @@ -17,6 +17,8 @@ import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.elements.adapters.AsynchronousDebugLabelAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; @@ -41,6 +43,14 @@ public abstract class AsynchronousModel { private Map fModelProxies = new HashMap(); // map of installed model proxies, by element private AsynchronousViewer fViewer; // viewer this model works for private boolean fDisposed = false; // whether disposed + + // debug flags + public static boolean DEBUG_MODEL = false; + + static { + DEBUG_MODEL = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/model")); //$NON-NLS-1$ + } /** * List of requests currently being performed. @@ -59,7 +69,15 @@ public abstract class AsynchronousModel { */ public AsynchronousModel(AsynchronousViewer viewer) { fViewer = viewer; - + if (DEBUG_MODEL) { + StringBuffer buffer = new StringBuffer(); + buffer.append("MODEL CREATED for: "); //$NON-NLS-1$ + buffer.append(fViewer); + buffer.append(" ("); //$NON-NLS-1$ + buffer.append(this); + buffer.append(")"); //$NON-NLS-1$ + DebugUIPlugin.debug(buffer.toString()); + } } /** @@ -83,6 +101,15 @@ public abstract class AsynchronousModel { * Disposes this model */ public synchronized void dispose() { + if (DEBUG_MODEL) { + StringBuffer buffer = new StringBuffer(); + buffer.append("MODEL DISPOSED for: "); //$NON-NLS-1$ + buffer.append(fViewer); + buffer.append(" ("); //$NON-NLS-1$ + buffer.append(this); + buffer.append(")"); //$NON-NLS-1$ + DebugUIPlugin.debug(buffer.toString()); + } fDisposed = true; cancelPendingUpdates(); disposeAllModelProxies(); @@ -475,6 +502,7 @@ public abstract class AsynchronousModel { ModelNode[] prevKids = null; ModelNode[] newChildren = null; + ModelNode[] unmap = null; synchronized (this) { if (isDisposed()) { @@ -490,57 +518,80 @@ public abstract class AsynchronousModel { } parentNode.setChildren(newChildren); } else { - for (int i = 0; i < prevKids.length; i++) { - ModelNode kid = prevKids[i]; - if (i >= children.length) { - kid.dispose(); - unmapNode(kid); - } else { - ModelNode prevNode = prevKids[i]; - Object nextChild = children[i]; - if (!prevNode.getElement().equals(nextChild)) { - unmapNode(prevNode); - } - mapElement(nextChild, prevNode); - } - } - // create new children - if (children.length > prevKids.length) { - newChildren = new ModelNode[children.length]; - System.arraycopy(prevKids, 0, newChildren, 0, prevKids.length); - for (int i = prevKids.length; i < children.length; i ++) { - Object child = children[i]; - ModelNode childNode = new ModelNode(parentNode, child); - mapElement(child, childNode); - newChildren[i] = childNode; - } - parentNode.setChildren(newChildren); - } - if (children.length < prevKids.length) { - newChildren = new ModelNode[children.length]; - System.arraycopy(prevKids, 0, newChildren, 0, children.length); - parentNode.setChildren(newChildren); - } - } + newChildren = new ModelNode[children.length]; + unmap = new ModelNode[prevKids.length]; + for (int i = 0; i < prevKids.length; i++) { + unmap[i] = prevKids[i]; + } + for (int i = 0; i < children.length; i++) { + Object child = children[i]; + boolean found = false; + for (int j = 0; j < prevKids.length; j++) { + ModelNode prevKid = prevKids[j]; + if (prevKid != null && child.equals(prevKid.getElement())) { + newChildren[i] = prevKid; + prevKids[j] = null; + found = true; + break; + } + } + if (!found) { + newChildren[i] = new ModelNode(parentNode, child); + mapElement(child, newChildren[i]); + } + } + for (int i = 0; i < prevKids.length; i++) { + ModelNode kid = prevKids[i]; + if (kid != null) { + kid.dispose(); + unmapNode(kid); + } + } + parentNode.setChildren(newChildren); + } + if (DEBUG_MODEL) { + DebugUIPlugin.debug("CHILDREN CHANGED: " + parentNode); //$NON-NLS-1$ + DebugUIPlugin.debug(toString()); + } } //update viewer outside the lock - final ModelNode[] finalPrevKids = prevKids; + final ModelNode[] finalUnmap = unmap; preservingSelection(new Runnable() { public void run() { - if (finalPrevKids != null) { - for (int i = 0; i < finalPrevKids.length; i++) { - ModelNode kid = finalPrevKids[i]; - if (i >= children.length) { - viewer.nodeDisposed(kid); - } else { - viewer.nodeChanged(kid); - } - } + if (finalUnmap != null) { + for (int i = 0; i < finalUnmap.length; i++) { + viewer.unmapNode(finalUnmap[i]); + } } - viewer.nodeChildrenChanged(parentNode); + viewer.nodeChildrenChanged(parentNode); } }); } + + public String toString() { + StringBuffer buf = new StringBuffer(); + if (fRoot != null) { + buf.append("ROOT: "); //$NON-NLS-1$ + append(buf, fRoot, 0); + } else { + buf.append("ROOT: null"); //$NON-NLS-1$ + } + return buf.toString(); + } + + private void append(StringBuffer buf, ModelNode node, int level) { + for (int i = 0; i < level; i++) { + buf.append('\t'); + } + buf.append(node); + buf.append('\n'); + ModelNode[] childrenNodes = node.getChildrenNodes(); + if (childrenNodes != null) { + for (int i = 0; i < childrenNodes.length; i++) { + append(buf, childrenNodes[i], level + 1); + } + } + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java index a6c60595d..f6eab7482 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java @@ -472,18 +472,23 @@ public class AsynchronousTableViewer extends AsynchronousViewer implements Liste } } } - - public void nodeChanged(ModelNode node) { - Widget widget = findItem(node); - if (widget != null && !widget.isDisposed()) { - if (widget instanceof TableItem) { - clear(widget); - return; - } - widget.setData(node.getElement()); - internalRefresh(node); + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChild(org.eclipse.swt.widgets.Widget, int) + */ + protected void clearChild(Widget parent, int childIndex) { + if (parent instanceof Table) { + fTable.clear(childIndex); } } - + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChildren(org.eclipse.swt.widgets.Widget) + */ + protected void clearChildren(Widget item) { + if (item instanceof Table) { + fTable.clearAll(); + } + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeModel.java index ef2835c71..7a4df83fd 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeModel.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeModel.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers; +import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor; import org.eclipse.jface.viewers.TreePath; @@ -130,16 +131,30 @@ public class AsynchronousTreeModel extends AsynchronousModel { if (parentNode == null) { return; } + int index = -1; synchronized (this) { + index = parentNode.getChildIndex(node); parentNode.removeChild(node); unmapNode(node); node.dispose(); + if (DEBUG_MODEL) { + DebugUIPlugin.debug("REMOVE: " + node); //$NON-NLS-1$ + DebugUIPlugin.debug(toString()); + } } + final int unmapFrom = index; final AsynchronousTreeViewer viewer = getTreeViewer(); preservingSelection(new Runnable() { public void run() { - viewer.nodeDisposed(node); - viewer.nodeChildrenChanged(parentNode); + // unmap the removed node and all children that were shifted + viewer.unmapNode(node); + if (unmapFrom > -1) { + ModelNode[] childrenNodes = parentNode.getChildrenNodes(); + for (int i = unmapFrom; i < childrenNodes.length; i++) { + viewer.unmapNode(childrenNodes[i]); + } + } + viewer.nodeChildRemoved(parentNode, unmapFrom); } }); } @@ -166,14 +181,17 @@ public class AsynchronousTreeModel extends AsynchronousModel { ModelNode node = new ModelNode(parent, element); parent.addChild(node); mapElement(element, node); + if (DEBUG_MODEL) { + DebugUIPlugin.debug("ADD: (parent) " + parent + " (child) " + element); //$NON-NLS-1$//$NON-NLS-2$ + DebugUIPlugin.debug(toString()); + } } //TODO sort??? // notify the viewer to update - // TODO: this could be more efficient by not refreshing all children preservingSelection(new Runnable() { public void run() { - getTreeViewer().nodeChildrenChanged(parent); + getTreeViewer().nodeChildrenAdded(parent); } }); @@ -240,12 +258,13 @@ public class AsynchronousTreeModel extends AsynchronousModel { * @param node * @param containsChildren */ - void setIsContainer(ModelNode node, boolean containsChildren) { - ModelNode[] prevChildren = null; + void setIsContainer(final ModelNode node, boolean containsChildren) { + ModelNode[] unmapChildren = null; synchronized (this) { - prevChildren = node.getChildrenNodes(); + ModelNode[] prevChildren = node.getChildrenNodes(); node.setIsContainer(containsChildren); if (!containsChildren && prevChildren != null) { + unmapChildren = prevChildren; for (int i = 0; i < prevChildren.length; i++) { ModelNode child = prevChildren[i]; unmapNode(child); @@ -253,22 +272,24 @@ public class AsynchronousTreeModel extends AsynchronousModel { } node.setChildren(null); } + if (DEBUG_MODEL) { + DebugUIPlugin.debug("SET CONTAINER: " + node); //$NON-NLS-1$ + DebugUIPlugin.debug(toString()); + } } // update tree outside lock - AsynchronousTreeViewer viewer = getTreeViewer(); - if (containsChildren) { - if (prevChildren == null) { - viewer.nodeChildrenChanged(node); - viewer.nodeContainerChanged(node); - } else { - viewer.nodeContainerChanged(node); - } - } else if (!containsChildren && prevChildren != null) { - for (int i = 0; i < prevChildren.length; i++) { - ModelNode child = prevChildren[i]; - viewer.nodeDisposed(child); - } - viewer.nodeChildrenChanged(node); - } + final ModelNode[] finalUnmap = unmapChildren; + preservingSelection(new Runnable() { + public void run() { + if (finalUnmap != null) { + for (int i = 0; i < finalUnmap.length; i++) { + getViewer().unmapNode(finalUnmap[i]); + } + } + getTreeViewer().nodeContainerChanged(node); + getViewer().nodeChildrenChanged(node); + } + }); + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java index f5156f8f1..dc6494d15 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java @@ -442,7 +442,7 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { return false; } } - if (widget instanceof TreeItem) { + if (widget instanceof TreeItem && !widget.isDisposed()) { TreeItem treeItem = (TreeItem) widget; if (treeItem.getExpanded()) { return path.getSegmentCount() == treePath.getSegmentCount(); @@ -747,28 +747,6 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { return paths; } - /** - * Container status of a node changed - * - * @param node - */ - protected void nodeContainerChanged(ModelNode node) { - Widget widget = findItem(node); - if (widget != null && !widget.isDisposed()) { - boolean expanded = true; - if (node.isContainer() && getItemCount(widget) == 0) { - setItemCount(widget, 1); - } - if (widget instanceof TreeItem) { - expanded = ((TreeItem) widget).getExpanded(); - } - if (expanded) { - updateChildren(node); - } - } - attemptPendingUpdates(); - } - protected int getItemCount(Widget widget) { if (widget instanceof TreeItem) { return ((TreeItem) widget).getItemCount(); @@ -870,8 +848,32 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { fTree.clearAll(true); } } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChildren(org.eclipse.swt.widgets.Widget) + */ + protected void clearChildren(Widget widget) { + if (widget instanceof TreeItem && !widget.isDisposed()) { + TreeItem item = (TreeItem) widget; + item.clearAll(true); + } else { + fTree.clearAll(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.AsynchronousViewer#clearChild(org.eclipse.swt.widgets.Widget, int) + */ + protected void clearChild(Widget parent, int childIndex) { + if (parent instanceof TreeItem && !parent.isDisposed()) { + TreeItem item = (TreeItem) parent; + item.clear(childIndex, true); + } else { + fTree.clear(childIndex, true); + } + } - /* + /* * (non-Javadoc) * * @see org.eclipse.debug.internal.ui.viewers.AsynchronousModelViewer#newSelectionFromWidget() @@ -1169,24 +1171,6 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { return new AsynchronousTreeModel(this); } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.AsynchronousModelViewer#nodeChanged(org.eclipse.debug.internal.ui.viewers.ModelNode) - */ - public void nodeChanged(ModelNode node) { - Widget widget = findItem(node); - if (widget != null && !widget.isDisposed()) { - if (widget instanceof TreeItem) { - clear(widget); - return; - } - widget.setData(node.getElement()); - mapElement(node, widget); - internalRefresh(node); - attemptPendingUpdates(); - } - } - /** * Attempt pending udpates. Subclasses may override but should call super. */ @@ -1563,4 +1547,26 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { } } } + + /** + * Notification the container status of a node has changed/been computed. + * + * @param node + */ + protected void nodeContainerChanged(ModelNode node) { + Widget widget = findItem(node); + if (widget != null && !widget.isDisposed()) { + if (node.isContainer()) { + if (widget instanceof TreeItem) { + if (((TreeItem)widget).getExpanded()) { + updateChildren(node); + } + } else { + updateChildren(node); + } + attemptPendingUpdates(); + } + } + } + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java index f77353ac9..a08fe753a 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java @@ -19,7 +19,9 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; @@ -113,16 +115,14 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis protected static final String OLD_LABEL = "old_label"; //$NON-NLS-1$ protected static final String OLD_IMAGE = "old_image"; //$NON-NLS-1$ - - /** - * Map of parent nodes for which children were needed to "set data" - * in the virtual widget. A parent is added to this map when we try go - * get children but they aren't there yet. The children are retrieved - * asynchronously, and later put back into the widgetry. - * The value is an array of ints of the indicies of the children that - * were requested. - */ - private Map fParentsPendingChildren = new HashMap(); + + // debug flags + public static boolean DEBUG_VIEWER = false; + + static { + DEBUG_VIEWER = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/viewer")); //$NON-NLS-1$ + } /** * Creates a new viewer @@ -238,7 +238,6 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) */ protected synchronized void inputChanged(Object input, Object oldInput) { - fParentsPendingChildren.clear(); if (fUpdatePolicy == null) { fUpdatePolicy = createUpdatePolicy(); fUpdatePolicy.init(this); @@ -832,35 +831,6 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis protected AsynchronousModel getModel() { return fModel; } - - /** - * A node has been disposed from the model. - * - * @param node - */ - protected void nodeDisposed(ModelNode node) { - Widget widget = findItem(node); - if (widget != null) { - unmapNode(node); - widget.dispose(); - } - } - - /** - * Unmaps the node from its widget and all of its children nodes from - * their widgets. - * - * @param node - */ - protected void unmapNode(ModelNode node) { - unmapElement(node); - ModelNode[] childrenNodes = node.getChildrenNodes(); - if (childrenNodes != null) { - for (int i = 0; i < childrenNodes.length; i++) { - unmapNode(childrenNodes[i]); - } - } - } /** * A node in the model has been updated @@ -870,8 +840,8 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis protected void nodeChanged(ModelNode node) { Widget widget = findItem(node); if (widget != null) { - widget.setData(node.getElement()); - internalRefresh(node); + clear(widget); + attemptPendingUpdates(); } } @@ -892,38 +862,26 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis } /** - * Called when nodes are set in the model. The children may not have been - * retrieved yet when the tree got the call to "set data". + * Clears the given widget * - * @param parent - * @param children + * @param item */ - protected void nodeChildrenSet(ModelNode parent, ModelNode[] children) { - int[] indicies = removePendingChildren(parent); - Widget widget = findItem(parent); - if (widget != null && !widget.isDisposed()) { - if (indicies != null) { - for (int i = 0; i < indicies.length; i++) { - int index = indicies[i]; - Widget item = getChildWidget(widget, index); - if (item != null) { - if (index < children.length) { - ModelNode childNode = children[index]; - mapElement(childNode, item); - item.setData(childNode.getElement()); - internalRefresh(childNode); - } - } - } - setItemCount(widget, children.length); - } else { - setItemCount(widget, children.length); - } - } - attemptPendingUpdates(); - } - protected abstract void clear(Widget item); + + /** + * Clears the children of the widget. + * + * @param item + */ + protected abstract void clearChildren(Widget item); + + /** + * Clears the child at the given index. + * + * @param parent + * @param childIndex + */ + protected abstract void clearChild(Widget parent, int childIndex); /** * Returns the child widet at the given index for the given parent or @@ -949,22 +907,69 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis protected void attemptPendingUpdates() { attemptSelection(false); } - + /** - * The children of a node have changed. + * Notification a node's children have changed. + * Updates the child count for the parent's widget + * and clears children to be updated. * - * @param parent + * @param parentNode */ protected void nodeChildrenChanged(ModelNode parentNode) { - ModelNode[] childrenNodes = parentNode.getChildrenNodes(); + Widget widget = findItem(parentNode); + if (widget != null && !widget.isDisposed()) { + int childCount = parentNode.getChildCount(); + setItemCount(widget, childCount); + clearChildren(widget); + attemptPendingUpdates(); + } + } + + /** + * Notification children have been added to the end + * of the given parent. + * + * @param parentNode + */ + protected void nodeChildrenAdded(ModelNode parentNode) { + Widget widget = findItem(parentNode); + if (widget != null && !widget.isDisposed()) { + int childCount = parentNode.getChildCount(); + setItemCount(widget, childCount); + attemptPendingUpdates(); + } + } + + /** + * Notification children have been added to the end + * of the given parent. + * + * @param parentNode + */ + protected void nodeChildRemoved(ModelNode parentNode, int index) { + Widget widget = findItem(parentNode); + if (widget != null && !widget.isDisposed()) { + int childCount = parentNode.getChildCount(); + setItemCount(widget, childCount); + for (int i = index; i < childCount; i ++) { + clearChild(widget, i); + } + attemptPendingUpdates(); + } + } + + /** + * Unmaps the node from its widget and all of its children nodes from + * their widgets. + * + * @param node + */ + protected void unmapNode(ModelNode node) { + unmapElement(node); + ModelNode[] childrenNodes = node.getChildrenNodes(); if (childrenNodes != null) { - nodeChildrenSet(parentNode, childrenNodes); - } else { - Widget widget = findItem(parentNode); - if (widget != null && !widget.isDisposed()) { - int childCount = parentNode.getChildCount(); - setItemCount(widget, childCount); - attemptPendingUpdates(); + for (int i = 0; i < childrenNodes.length; i++) { + unmapNode(childrenNodes[i]); } } } @@ -997,38 +1002,6 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis return findItem((Object)node); } - /** - * Note that the child at the specified index was requested by a widget - * when revealed but that the data was not in the model yet. When the data - * becomes available, map it to its widget. - * - * @param parent - * @param index - */ - protected synchronized void addPendingChildIndex(ModelNode parent, int index) { - int[] indicies = (int[]) fParentsPendingChildren.get(parent); - if (indicies == null) { - indicies = new int[]{index}; - } else { - int[] next = new int[indicies.length + 1]; - System.arraycopy(indicies, 0, next, 0, indicies.length); - next[indicies.length] = index; - indicies = next; - } - fParentsPendingChildren.put(parent, indicies); - } - - /** - * Removes and returns and children indicies that were pending for the given - * parent node. May return <code>null</code>. - * - * @param parent - * @return indicies of children that data were requested for or <code>null</code> - */ - protected int[] removePendingChildren(ModelNode parent) { - return (int[]) fParentsPendingChildren.remove(parent); - } - /* * (non-Javadoc) * @@ -1042,6 +1015,12 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis Widget parentItem = getParentWidget(event.item); int index = event.index; + if (DEBUG_VIEWER) { + DebugUIPlugin.debug("SET DATA [" + index + "]: " + parentItem); //$NON-NLS-1$//$NON-NLS-2$ + } + if (index == -1) { + return; + } ModelNode[] nodes = getModel().getNodes(parentItem.getData()); if (nodes != null) { @@ -1054,20 +1033,42 @@ public abstract class AsynchronousViewer extends StructuredViewer implements Lis final ModelNode child = childrenNodes[index]; mapElement(child, event.item); event.item.setData(child.getElement()); + if (DEBUG_VIEWER) { + DebugUIPlugin.debug("\tPARENT: " + node); //$NON-NLS-1$ + DebugUIPlugin.debug("\tMAPPED: " + child); //$NON-NLS-1$ + Widget[] widgets = findItems(child); + if (widgets.length != 1) { + DebugUIPlugin.debug("\t\t*** NODE MAPPED > 1 ITEM ***"); //$NON-NLS-1$ + for (int j = 0; j < widgets.length; j++) { + DebugUIPlugin.debug("\t\t\t" + widgets[j]); //$NON-NLS-1$ + } + } + } preservingSelection(new Runnable() { public void run() { internalRefresh(child); } }); - } else { - addPendingChildIndex(node, index); - } + } return; + } else { + if (DEBUG_VIEWER) { + Widget[] widgets = findItems(node); + DebugUIPlugin.debug("\tITEM NOT FOUND: " + node); //$NON-NLS-1$ + DebugUIPlugin.debug("\tITEMS WERE: "); //$NON-NLS-1$ + for (int j = 0; j < widgets.length; j++) { + DebugUIPlugin.debug("\t\t" + widgets[j]); //$NON-NLS-1$ + } + } } } + } else { + if (DEBUG_VIEWER) { + DebugUIPlugin.debug("\tNOT FOUND IN MODEL: " + parentItem.getData()); //$NON-NLS-1$ + } } - } - + } + protected abstract void restoreLabels(Item item); /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ModelNode.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ModelNode.java index b52c9736e..ee2eddeff 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ModelNode.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ModelNode.java @@ -194,4 +194,16 @@ public class ModelNode { fIsContainer = container; } + public String toString() { + StringBuffer buf = new StringBuffer(); + if (isDisposed()) { + buf.append("[DISPOSED] "); //$NON-NLS-1$ + } + if (isContainer()) { + buf.append("[+] "); //$NON-NLS-1$ + } + buf.append(getElement()); + return buf.toString(); + } + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java index c1831193b..c3ff894e4 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java @@ -43,6 +43,12 @@ public class ProcessProxy extends EventHandlerModelProxy { protected void handleCreate(DebugEvent event) { // do nothing - Launch change notification handles this } + + protected void handleTerminate(DebugEvent event) { + handleChange(event); + } + + }; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java index 7b9831328..34ee11bdd 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java @@ -488,11 +488,8 @@ abstract public class AsyncVirtualContentTableViewer extends AsynchronousTableVi // is causing the table viewer to not scroll or move cursor properly. // #interalRefresh on a child will never cause a structural // change in a table viewer. As a result, there is no need to preserve selection - internalRefresh(child); - - } else { - addPendingChildIndex(node, index); - } + internalRefresh(child); + } return; } } |