Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2012-09-13 17:56:20 -0400
committerPawel Piech2012-09-14 13:13:57 -0400
commit63521f907e337fdef6ce99641b3a3efd8663df3f (patch)
tree4cc2cdeb165a94214149b32db99f868af10c55e1
parent1297645ef163557ea8c68ddbc419867acc6a38d8 (diff)
downloadorg.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
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java22
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java69
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);
+ }
+ }
}

Back to the top