diff options
author | Eugene Tarassov | 2012-09-13 21:56:20 +0000 |
---|---|---|
committer | Pawel Piech | 2012-09-14 17:13:57 +0000 |
commit | 63521f907e337fdef6ce99641b3a3efd8663df3f (patch) | |
tree | 4cc2cdeb165a94214149b32db99f868af10c55e1 | |
parent | 1297645ef163557ea8c68ddbc419867acc6a38d8 (diff) | |
download | org.eclipse.tcf-63521f907e337fdef6ce99641b3a3efd8663df3f.tar.gz org.eclipse.tcf-63521f907e337fdef6ce99641b3a3efd8663df3f.tar.xz org.eclipse.tcf-63521f907e337fdef6ce99641b3a3efd8663df3f.zip |
Bug 389197 - [debug view] If user expands stack trace, it should re-expand after a suspended event
Conflicts:
plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java
2 files changed, 79 insertions, 12 deletions
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java index 0a25cf38c..b37550a91 100644 --- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java +++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java @@ -81,6 +81,8 @@ import org.eclipse.swt.graphics.Device; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.core.Command; +import org.eclipse.tcf.debug.ui.ITCFSourceDisplay; import org.eclipse.tcf.internal.debug.actions.TCFAction; import org.eclipse.tcf.internal.debug.launch.TCFSourceLookupDirector; import org.eclipse.tcf.internal.debug.launch.TCFSourceLookupParticipant; @@ -103,8 +105,6 @@ import org.eclipse.tcf.internal.debug.ui.commands.StepReturnCommand; import org.eclipse.tcf.internal.debug.ui.commands.SuspendCommand; import org.eclipse.tcf.internal.debug.ui.commands.TerminateCommand; import org.eclipse.tcf.internal.debug.ui.preferences.TCFPreferences; -import org.eclipse.tcf.core.Command; -import org.eclipse.tcf.debug.ui.ITCFSourceDisplay; import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IErrorReport; import org.eclipse.tcf.protocol.IService; @@ -288,8 +288,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, private final Map<String,Object> context_map = new HashMap<String,Object>(); - private final Set<String> expanded_nodes = new HashSet<String>(); - private final Map<IWorkbenchPart,TCFNode> pins = new HashMap<IWorkbenchPart,TCFNode>(); private final Map<IWorkbenchPart,TCFSnapshot> locks = new HashMap<IWorkbenchPart,TCFSnapshot>(); private final Map<IWorkbenchPart,Integer> lock_policy = new HashMap<IWorkbenchPart,Integer>(); @@ -898,7 +896,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, action_results.remove(id); Object o = context_map.remove(id); if (o instanceof CreateNodeRunnable) ((CreateNodeRunnable)o).onContextRemoved(); - expanded_nodes.remove(id); + for (TCFModelProxy proxy : model_proxies.values()) { + proxy.clearAutoExpandStack(id); + } if (mem_blocks_update != null) mem_blocks_update.changeset.remove(id); } launch_node.onAnyContextAddedOrRemoved(); @@ -1488,14 +1488,16 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, if (node.isDisposed()) return; runSuspendTrigger(node); if (reason == null) return; - if (reason.equals(IRunControl.REASON_USER_REQUEST)) return; for (TCFModelProxy proxy : model_proxies.values()) { if (proxy.getPresentationContext().getId().equals(IDebugUIConstants.ID_DEBUG_VIEW)) { + boolean user_request = + reason.equals(IRunControl.REASON_USER_REQUEST) || + reason.equals(IRunControl.REASON_STEP) || + reason.equals(IRunControl.REASON_CONTAINER) || + delay_stack_update_until_last_step && launch.getContextActionsCount(node.id) != 0; + if (proxy.getAutoExpandNode(node.id, user_request)) proxy.expand(node); + if (reason.equals(IRunControl.REASON_USER_REQUEST)) continue; proxy.setSelection(node); - if (reason.equals(IRunControl.REASON_STEP)) continue; - if (reason.equals(IRunControl.REASON_CONTAINER)) continue; - if (delay_stack_update_until_last_step && launch.getContextActionsCount(node.id) != 0) continue; - if (expanded_nodes.add(node.id)) proxy.expand(node); } if (reason.equals(IRunControl.REASON_BREAKPOINT)) { IWorkbenchPart part = proxy.getPresentationContext().getPart(); diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java index c00e19adc..b5591f105 100644 --- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java +++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java @@ -11,12 +11,14 @@ package org.eclipse.tcf.internal.debug.ui.model; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer; @@ -32,7 +34,10 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateList import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.viewers.ITreeViewerListener; +import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.widgets.Display; @@ -45,10 +50,10 @@ import org.eclipse.tcf.protocol.Protocol; * Model proxy listeners are debuggers views. */ @SuppressWarnings("restriction") -public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Runnable { +public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Runnable, ITreeViewerListener { private static final TCFNode[] EMPTY_NODE_ARRAY = new TCFNode[0]; - + private static boolean is_linux = "Linux".equals(System.getProperty("os.name")); private final TCFModel model; private final TCFLaunch launch; private final Display display; @@ -58,6 +63,7 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru private final Set<ModelDelta> content_deltas = new HashSet<ModelDelta>(); private final LinkedList<TCFNode> selection = new LinkedList<TCFNode>(); private final Set<String> auto_expand_set = new HashSet<String>(); + private Map<String, Boolean> expanded_nodes = Collections.synchronizedMap(new TreeMap<String, Boolean>()); private boolean posted; private boolean installed; @@ -196,6 +202,9 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru public void installed(Viewer viewer) { if (isDisposed()) return; super.installed(viewer); + if (is_linux && viewer instanceof TreeViewer) { + ((TreeViewer)viewer).addTreeListener(this); + } Protocol.invokeAndWait(new Runnable() { public void run() { assert !installed; @@ -224,6 +233,9 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru disposed = true; } }); + if (is_linux && getViewer() instanceof TreeViewer) { + ((TreeViewer)getViewer()).removeTreeListener(this); + } super.dispose(); } @@ -279,6 +291,44 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru } /** + * Returns true if node should be be expanded upon the first suspended event. + * If the given context ID is seen for the first time, the node should be + * expanded unless the event was caused by user request. In the latter case + * the node should not be expanded. + * <p> + * Note: As a workaround for bug 208939 on Linux, the auto-expansion is + * enabled even after the first suspend event. User collapse/expand actions + * are tracked to determine whether a given node should be expanded. + * </p> + * @param id Id of execution node to check. + * @param user_request Flag whether the state is requested in response + * to a user-requested suspend event. + */ + boolean getAutoExpandNode(String id, boolean user_request) { + Boolean expand = null; + synchronized(expanded_nodes) { + expand = expanded_nodes.get(id); + if (expand == null) { + if (user_request) { + expand = Boolean.FALSE; + } + else { + expand = Boolean.TRUE; + expanded_nodes.put(id, is_linux); + } + } + } + return expand; + } + + /** + * Clear auto-expand info when a node is removed. + */ + void clearAutoExpandStack(String id) { + expanded_nodes.remove(id) ; + } + + /** * Get current value of the view input. * @return view input object. */ @@ -565,4 +615,19 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru launch.removePendingClient(this); } } + + public void treeCollapsed(TreeExpansionEvent event) { + updateExpandStack(event, false); + } + + public void treeExpanded(TreeExpansionEvent event) { + updateExpandStack(event, true); + } + + private void updateExpandStack(TreeExpansionEvent event, final boolean expand) { + if (event.getElement() instanceof TCFNodeExecContext) { + TCFNodeExecContext node = (TCFNodeExecContext)event.getElement(); + if (model == node.getModel()) expanded_nodes.put(node.id, expand); + } + } } |