Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Piech2010-10-08 15:49:41 +0000
committerPawel Piech2010-10-08 15:49:41 +0000
commitc430a195e2308070424637613332c6e29b4887d4 (patch)
treec6cee64b50216e46c86e85c98293de692f357db5
parent96165aa6c4ba99aef72760b19363a07abe3f26d9 (diff)
downloadeclipse.platform.debug-c430a195e2308070424637613332c6e29b4887d4.tar.gz
eclipse.platform.debug-c430a195e2308070424637613332c6e29b4887d4.tar.xz
eclipse.platform.debug-c430a195e2308070424637613332c6e29b4887d4.zip
Bug 326917 - [Fiexible Hierarchy] View state is not saved correctly when top view element is deep in a tree hierarchy.
-rw-r--r--org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java212
-rw-r--r--org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java30
-rw-r--r--org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java144
-rw-r--r--org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java100
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java4
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ITreeModelContentProvider.java13
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java13
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java2
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java20
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/SubTreeModelViewer.java4
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java34
11 files changed, 516 insertions, 60 deletions
diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java
index bb7464806..e3a1eef41 100644
--- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java
@@ -125,13 +125,18 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda
Assert.assertNotNull("Top item should not be null!", originalTopPath);
// Bug 116105: On a Mac the reveal call is not reliable. Use the viewer returned path instead.
// Assert.assertEquals(elements[indexRevealElem], originalTopPath.getLastSegment());
-
+
+ // Extract the original state from viewer
+ ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
+ fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
+
// Set the viewer input to null. This will trigger the view to save the viewer state.
fListener.reset(true, false);
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
- while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
// Set the viewer input back to the model to trigger RESTORE operation.
fListener.reset(false, false);
@@ -212,13 +217,17 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda
getCTargetViewer().reveal(TreePath.EMPTY, 1);
while(fDisplay.readAndDispatch()) {}
final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
+ Assert.assertNotNull("Top item should not be null!", originalTopPath);
// Bug 116105: On a Mac the reveal call is not reliable. Use the viewer returned path instead.
- // Assert.assertNotNull("Top item should not be null!", originalTopPath);
- Assert.assertEquals(elements[1], originalTopPath.getLastSegment());
-
+ //Assert.assertEquals(elements[1], originalTopPath.getLastSegment());
+
+ // Extract the original state from viewer
+ ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
+ fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
+
// Set the viewer input to null. This will trigger the view to save the viewer state.
fListener.reset(true, false);
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
@@ -292,13 +301,18 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda
while(fDisplay.readAndDispatch()) {}
final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
Assert.assertNotNull("Top item should not be null!", originalTopPath);
-
+
+ // Extract the original state from viewer
+ ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
+ fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
+
// Set the viewer input to null. This will trigger the view to save the viewer state.
fListener.reset(true, false);
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
- while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
// Set the viewer input back to the model.
fListener.reset(false, false);
@@ -311,4 +325,182 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda
Assert.assertNotNull("Top item should not be null!", topPath);
Assert.assertEquals(originalTopPath, topPath);
}
+
+ /**
+ * Test for bug 326965.<br>
+ * This test verifies that canceling a reveal pending state delta is
+ * properly handled when a new reveal delta is received from the model.
+ */
+ public void testRestoreRevealAfterRevealCancel() {
+ TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
+ TestModel model = TestModel.simpleMultiLevel();
+
+ // Expand all
+ fViewer.setAutoExpandLevel(-1);
+
+ // Create the listener.
+ fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);
+
+ // Set the input into the view and update the view.
+ fViewer.setInput(model.getRootElement());
+ while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ model.validateData(fViewer, TreePath.EMPTY, true);
+
+ // Stop autopopulating the view.
+ autopopulateAgent.dispose();
+
+ // Set top index of view to element "3" and wait for view to repaint.
+ getCTargetViewer().reveal(TreePath.EMPTY, 2);
+ while(fDisplay.readAndDispatch()) {}
+
+ // Trigger save of state.
+ fListener.reset();
+ fViewer.setInput(null);
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE)) fDisplay.sleep ();
+
+ // Set input back to root element.
+ // Note: Wait only for the processing of the delta and the start of state restore, not for all updates
+ fListener.reset();
+ TreePath elementPath = model.findElement("3");
+ fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 1, STATE_UPDATES);
+ fViewer.setInput(model.getRootElement());
+ while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+
+ // Update the viewer with new selection delta to something new in the view
+ ModelDelta revealDelta = model.makeElementDelta(model.findElement("2.1"), IModelDelta.REVEAL);
+
+ // Wait for the second model delta to process
+ fListener.reset();
+ model.postDelta(revealDelta);
+ while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CONTENT_UPDATES_COMPLETE))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+
+ // Clear view then reset it again.
+ fListener.reset();
+ fViewer.setInput(null);
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE)) fDisplay.sleep ();
+
+ autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
+ fViewer.setInput(model.getRootElement());
+ while (!fListener.isFinished(STATE_RESTORE_COMPLETE))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ autopopulateAgent.dispose();
+ }
+
+ /**
+ * Test for bug 326965.<br>
+ * This test verifies that canceling a reveal pending state delta is
+ * properly handled when a new reveal delta is received from the model.
+ */
+ public void testRestoreRevealAfterRevealCancel2() {
+ TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
+ TestModel model = TestModel.simpleMultiLevel();
+
+ // Expand all
+ fViewer.setAutoExpandLevel(-1);
+
+ // Create the listener.
+ fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);
+
+ // Set the input into the view and update the view.
+ fViewer.setInput(model.getRootElement());
+ while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ model.validateData(fViewer, TreePath.EMPTY, true);
+
+ // Stop autopopulating the view.
+ autopopulateAgent.dispose();
+
+ // Set top index of view to element "3" and wait for view to repaint.
+ getCTargetViewer().reveal(TreePath.EMPTY, 2);
+ while(fDisplay.readAndDispatch()) {}
+
+ // Trigger save of state.
+ fListener.reset();
+ fViewer.setInput(null);
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE)) fDisplay.sleep ();
+
+ // Set input back to root element.
+ // Note: Wait only for the processing of the delta and the start of state restore, not for all updates
+ fListener.reset();
+ final TreePath elementPath = model.findElement("3");
+ fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 0, STATE_UPDATES);
+ fViewer.setInput(model.getRootElement());
+ while (!fListener.isFinished(STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+
+ // Update the viewer with new selection delta to something new in the view
+ TreePath pathToBeRevealed = model.findElement("2.1");
+ ModelDelta revealDelta = model.makeElementDelta(pathToBeRevealed, IModelDelta.REVEAL);
+
+ // Wait for the second model delta to process
+ fListener.reset();
+ model.postDelta(revealDelta);
+ while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CONTENT_UPDATES_COMPLETE))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+
+ while (fDisplay.readAndDispatch ()) {}
+ // check if REVEAL was restored OK
+ TreePath topPath = getCTargetViewer().getTopElementPath();
+ Assert.assertNotNull("Top item should not be null!", topPath);
+ Assert.assertEquals(pathToBeRevealed, topPath);
+
+ }
+
+
+ /**
+ * Restore REVEAL when having also to restore an expanded element
+ * that is just above the REVEAL element.
+ *
+ * See bug 324100
+ */
+ public void testRestoreDeepTreeAndReveal() {
+ TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
+
+ TestModel model = TestModel.simpleDeepMultiLevel();
+ fViewer.setAutoExpandLevel(-1);
+
+ // Create the listener, only check the first level
+ fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);
+
+
+ // Set the input into the view and update the view.
+ fViewer.setInput(model.getRootElement());
+
+ while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ model.validateData(fViewer, TreePath.EMPTY, true);
+
+ // Stop forcing view updates.
+ autopopulateAgent.dispose();
+
+ // Scroll down to the last part of the tree.
+ getCTargetViewer().reveal(model.findElement("3.6.3.16.16.16.16.16"), 1);
+ while(fDisplay.readAndDispatch()) {}
+ final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
+ Assert.assertNotNull("Top item should not be null!", originalTopPath);
+
+ // Extract the original state from viewer
+ ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
+ fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
+
+ // Set the viewer input to null. This will trigger the view to save the viewer state.
+ fListener.reset(true, false);
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
+ fViewer.setInput(null);
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+
+ // Set the viewer input back to the model
+ fListener.reset(false, false);
+ fListener.addUpdates(getCTargetViewer(), originalTopPath, (TestElement)originalTopPath.getLastSegment(), 0, STATE_UPDATES);
+ fViewer.setInput(model.getRootElement());
+ while (!fListener.isFinished(STATE_UPDATES | CONTENT_UPDATES_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+
+ while (fDisplay.readAndDispatch ()) {}
+ // check if REVEAL was restored OK
+ final TreePath topPath = getCTargetViewer().getTopElementPath();
+ Assert.assertNotNull("Top item should not be null!", topPath);
+ Assert.assertEquals(originalTopPath, topPath);
+
+ }
+
}
diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java
index 62cd5b9e3..3699b083b 100644
--- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java
@@ -744,10 +744,11 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi
fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
// Set the viewer input to null. This will trigger the view to save the viewer state.
- fListener.reset(true, false);
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.reset(false, false);
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
- while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
// Set the viewer input back to the model. When view updates are complete
// the viewer
@@ -794,10 +795,11 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi
// Set the viewer input to null. This will trigger the view to save the viewer state.
fListener.reset(true, false);
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
- while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
// Set the viewer input back to the model. When view updates are complete
// the viewer
@@ -837,12 +839,17 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi
fViewer.setSelection(originalSelection);
Assert.assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
+ // Extract the original state from viewer
+ ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
+ fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
+
// Set the viewer input to null. This will trigger the view to save the viewer state.
fListener.reset();
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
- while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
// Set the viewer input back to the model. When view updates are complete
// the viewer
@@ -889,12 +896,17 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi
fViewer.setSelection(originalSelection);
Assert.assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
+ // Extract the original state from viewer
+ ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
+ fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);
+
// Set the viewer input to null. This will trigger the view to save the viewer state.
fListener.reset();
- fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
+ fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
fViewer.setInput(null);
- while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
+ while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES))
+ if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
TestElement[] elements = model.getRootElement().getChildren();
diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java
index 8a3287849..609ce9838 100644
--- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java
+++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java
@@ -624,7 +624,7 @@ public class TestModel implements IElementContentProvider, IElementLabelProvider
}) );
return model;
}
-
+
public static TestModel compositeMultiLevel() {
TestModel m2 = new TestModel();
m2.setRoot( new TestElement(m2, "m2.root", new TestElement[] {
@@ -670,5 +670,145 @@ public class TestModel implements IElementContentProvider, IElementLabelProvider
return m1;
}
-
+ public static TestModel simpleDeepMultiLevel() {
+ TestModel model = new TestModel();
+ model.setRoot( new TestElement(model, "root", new TestElement[] {
+ new TestElement(model, "1", new TestElement[0]),
+ new TestElement(model, "2", true, false, new TestElement[] {
+ new TestElement(model, "2.1", true, true, new TestElement[0]),
+ new TestElement(model, "2.2", false, true, new TestElement[0]),
+ new TestElement(model, "2.3", true, false, new TestElement[0]),
+ }),
+ new TestElement(model, "3", new TestElement[] {
+ new TestElement(model, "3.1", new TestElement[] {
+ new TestElement(model, "3.1.1", new TestElement[0]),
+ new TestElement(model, "3.1.2", new TestElement[0]),
+ new TestElement(model, "3.1.3", new TestElement[0]),
+ }),
+ new TestElement(model, "3.2", new TestElement[] {
+ new TestElement(model, "3.2.1", new TestElement[0]),
+ new TestElement(model, "3.2.2", new TestElement[0]),
+ new TestElement(model, "3.2.3", new TestElement[0]),
+ }),
+ new TestElement(model, "3.3", new TestElement[] {
+ new TestElement(model, "3.3.1", new TestElement[0]),
+ new TestElement(model, "3.3.2", new TestElement[0]),
+ new TestElement(model, "3.3.3", new TestElement[0]),
+ }),
+ new TestElement(model, "3.4", new TestElement[] {
+ new TestElement(model, "3.4.1", new TestElement[0]),
+ new TestElement(model, "3.4.2", new TestElement[0]),
+ new TestElement(model, "3.4.3", new TestElement[0]),
+ }),
+ new TestElement(model, "3.5", new TestElement[] {
+ new TestElement(model, "3.5.1", new TestElement[0]),
+ new TestElement(model, "3.5.2", new TestElement[0]),
+ new TestElement(model, "3.5.3", new TestElement[0]),
+ }),
+ new TestElement(model, "3.6", new TestElement[] {
+ new TestElement(model, "3.6.1", new TestElement[0]),
+ new TestElement(model, "3.6.2", new TestElement[0]),
+ new TestElement(model, "3.6.3", new TestElement[] {
+ new TestElement(model, "3.6.3.1", new TestElement[0]),
+ new TestElement(model, "3.6.3.2", new TestElement[0]),
+ new TestElement(model, "3.6.3.4", new TestElement[0]),
+ new TestElement(model, "3.6.3.5", new TestElement[0]),
+ new TestElement(model, "3.6.3.6", new TestElement[0]),
+ new TestElement(model, "3.6.3.7", new TestElement[0]),
+ new TestElement(model, "3.6.3.8", new TestElement[0]),
+ new TestElement(model, "3.6.3.9", new TestElement[0]),
+ new TestElement(model, "3.6.3.10", new TestElement[0]),
+ new TestElement(model, "3.6.3.11", new TestElement[0]),
+ new TestElement(model, "3.6.3.12", new TestElement[0]),
+ new TestElement(model, "3.6.3.13", new TestElement[0]),
+ new TestElement(model, "3.6.3.14", new TestElement[0]),
+ new TestElement(model, "3.6.3.15", new TestElement[0]),
+ new TestElement(model, "3.6.3.16", new TestElement[] {
+ new TestElement(model, "3.6.3.16.1", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.2", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.4", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.5", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.6", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.7", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.8", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.9", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.10", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.11", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.12", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.13", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.14", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.15", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16", new TestElement[] {
+ new TestElement(model, "3.6.3.16.16.1", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.2", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.4", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.5", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.6", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.7", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.8", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.9", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.10", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.11", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.12", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.13", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.14", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.15", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16", new TestElement[] {
+ new TestElement(model, "3.6.3.16.16.16.1", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.2", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.4", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.5", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.6", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.7", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.8", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.9", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.10", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.11", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.12", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.13", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.14", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.15", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16", new TestElement[] {
+ new TestElement(model, "3.6.3.16.16.16.16.1", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.2", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.4", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.5", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.6", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.7", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.8", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.9", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.10", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.11", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.12", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.13", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.14", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.15", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16", new TestElement[] {
+ new TestElement(model, "3.6.3.16.16.16.16.16.1", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.2", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.4", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.5", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.6", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.7", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.8", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.9", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.10", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.11", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.12", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.13", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.14", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.15", new TestElement[0]),
+ new TestElement(model, "3.6.3.16.16.16.16.16.16", new TestElement[0]),
+ }),
+ }),
+ }),
+ }),
+ }),
+ }),
+ }),
+ })
+ }) );
+ return model;
+ }
+
}
diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java
index 4a0063ce6..0764542ca 100644
--- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java
+++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java
@@ -11,6 +11,7 @@
*******************************************************************************/
package org.eclipe.debug.tests.viewer.model;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -21,6 +22,11 @@ import java.util.TreeSet;
import junit.framework.Assert;
import org.eclipe.debug.tests.viewer.model.TestModel.TestElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.internal.ui.viewers.model.ElementCompareRequest;
import org.eclipse.debug.internal.ui.viewers.model.ILabelUpdateListener;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer;
@@ -38,10 +44,12 @@ import org.eclipse.jface.viewers.TreePath;
public class TestModelUpdatesListener
implements IViewerUpdateListener, ILabelUpdateListener, IModelChangedListener, ITestModelUpdatesListenerConstants,
- IStateUpdateListener
+ IStateUpdateListener, IJobChangeListener
{
private final ITreeModelViewer fViewer;
+ private IStatus fJobError;
+
private boolean fFailOnRedundantUpdates;
private Set fRedundantUpdates = new HashSet();
@@ -87,6 +95,7 @@ public class TestModelUpdatesListener
public TestModelUpdatesListener(ITreeModelViewer viewer) {
fViewer = viewer;
+ Job.getJobManager().addJobChangeListener(this);
fViewer.addLabelUpdateListener(this);
fViewer.addModelChangedListener(this);
fViewer.addStateUpdateListener(this);
@@ -94,13 +103,25 @@ public class TestModelUpdatesListener
}
public void dispose() {
+ Job.getJobManager().removeJobChangeListener(this);
fViewer.removeLabelUpdateListener(this);
fViewer.removeModelChangedListener(this);
fViewer.removeStateUpdateListener(this);
fViewer.removeViewerUpdateListener(this);
}
-
+ public void aboutToRun(IJobChangeEvent event) {}
+ public void awake(IJobChangeEvent event) {}
+ public void running(IJobChangeEvent event) {}
+ public void scheduled(IJobChangeEvent event) {}
+ public void sleeping(IJobChangeEvent event) {}
+ public void done(IJobChangeEvent event) {
+ IStatus result = event.getJob().getResult();
+ if (result != null && result.getSeverity() == IStatus.ERROR) {
+ fJobError = result;
+ }
+ }
+
public void setFailOnRedundantUpdates(boolean failOnRedundantUpdates) {
fFailOnRedundantUpdates = failOnRedundantUpdates;
}
@@ -138,6 +159,7 @@ public class TestModelUpdatesListener
}
public void reset() {
+ fJobError = null;
fRedundantUpdates.clear();
fMultipleLabelUpdateSequencesObserved = false;
fMultipleModelUpdateSequencesObserved = false;
@@ -158,6 +180,7 @@ public class TestModelUpdatesListener
fViewerUpdatesComplete = false;
fLabelUpdatesStarted = false;
fLabelUpdatesComplete = false;
+ fStateUpdates.clear();
fStateSaveStarted = false;
fStateSaveComplete = false;
fStateRestoreStarted = false;
@@ -221,11 +244,40 @@ public class TestModelUpdatesListener
addUpdates(viewer, path, element, -1, STATE_UPDATES);
}
+ public void addStateUpdates(ITreeModelContentProviderTarget viewer, IModelDelta pendingDelta, int deltaFlags) {
+ TreePath treePath = getViewerTreePath(pendingDelta);
+ if ( !TreePath.EMPTY.equals(treePath) && (pendingDelta.getFlags() & deltaFlags) != 0 ) {
+ addUpdates(viewer, treePath, (TestElement)treePath.getLastSegment(), 0, STATE_UPDATES);
+ }
+ IModelDelta[] childDeltas = pendingDelta.getChildDeltas();
+ for (int i = 0; i < childDeltas.length; i++) {
+ addStateUpdates(viewer, childDeltas[i], deltaFlags);
+ }
+ }
+
+ /**
+ * 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 list = new ArrayList();
+ IModelDelta parentDelta = node.getParentDelta();
+ while (parentDelta != null) {
+ list.add(0, node.getElement());
+ node = parentDelta;
+ parentDelta = node.getParentDelta();
+ }
+ return new TreePath(list.toArray());
+ }
+
public void addUpdates(TreePath path, TestElement element, int levels, int flags) {
addUpdates(null, path, element, levels, flags);
}
- public void addUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element, int levels, int flags) {
+ public void addUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element, int levels, int flags) {
if (!path.equals(TreePath.EMPTY)) {
if ((flags & LABEL_UPDATES) != 0) {
fLabelUpdates.add(path);
@@ -233,10 +285,14 @@ public class TestModelUpdatesListener
if ((flags & HAS_CHILDREN_UPDATES) != 0) {
fHasChildrenUpdatesScheduled.add(path);
}
+
+ if ((flags & STATE_UPDATES) != 0 && viewer != null) {
+ fStateUpdates.add(path);
+ }
}
if (levels-- != 0) {
- TestElement[] children = element.getChildren();
+ TestElement[] children = element.getChildren();
if (children.length > 0 && (viewer == null || path.getSegmentCount() == 0 || viewer.getExpandedState(path))) {
if ((flags & CHILD_COUNT_UPDATES) != 0) {
fChildCountUpdatesScheduled.add(path);
@@ -249,10 +305,6 @@ public class TestModelUpdatesListener
fChildrenUpdatesScheduled.put(path, childrenIndexes);
}
- if ((flags & STATE_UPDATES) != 0 && viewer != null) {
- fStateUpdates.add(path);
- }
-
for (int i = 0; i < children.length; i++) {
addUpdates(viewer, path.createChildPath(children[i]), children[i], levels, flags);
}
@@ -277,7 +329,7 @@ public class TestModelUpdatesListener
}
public boolean isTimedOut() {
- return fTimeoutInterval > 0 && fTimeoutTime < System.currentTimeMillis();
+ return false && fTimeoutInterval > 0 && fTimeoutTime < System.currentTimeMillis();
}
public boolean isFinished(int flags) {
@@ -285,6 +337,10 @@ public class TestModelUpdatesListener
throw new RuntimeException("Timed Out: " + toString(flags));
}
+ if (fJobError != null) {
+ throw new RuntimeException("Job Error: " + fJobError);
+ }
+
if (fFailOnRedundantUpdates && !fRedundantUpdates.isEmpty()) {
Assert.fail("Redundant Updates: " + fRedundantUpdates.toString());
}
@@ -343,6 +399,11 @@ public class TestModelUpdatesListener
if ( (flags & STATE_RESTORE_STARTED) != 0) {
if (!fStateRestoreStarted) return false;
}
+ if ( (flags & STATE_UPDATES) != 0) {
+ if (!fStateUpdates.isEmpty()) {
+ return false;
+ }
+ }
if ( (flags & MODEL_PROXIES_INSTALLED) != 0) {
if (fProxyModels.size() != 0) return false;
}
@@ -484,6 +545,9 @@ public class TestModelUpdatesListener
}
public void stateUpdateComplete(Object input, IViewerUpdate update) {
+ if ( !(update instanceof ElementCompareRequest) || ((ElementCompareRequest)update).isEqual()) {
+ fStateUpdates.remove(update.getElementPath());
+ }
}
public void stateUpdateStarted(Object input, IViewerUpdate update) {
@@ -492,6 +556,18 @@ public class TestModelUpdatesListener
private String toString(int flags) {
StringBuffer buf = new StringBuffer("Viewer Update Listener");
+ if (fJobError != null) {
+ buf.append("\n\t");
+ buf.append("fJobError = " + fJobError);
+ if (fJobError.getException() != null) {
+ StackTraceElement[] trace = fJobError.getException().getStackTrace();
+ for (int i = 0; i < trace.length; i++) {
+ buf.append("\n\t\t");
+ buf.append(trace[i]);
+ }
+ }
+ }
+
if (fFailOnRedundantUpdates) {
buf.append("\n\t");
buf.append("fRedundantUpdates = " + fRedundantUpdates);
@@ -588,6 +664,10 @@ public class TestModelUpdatesListener
buf.append("\n\t");
buf.append("fProxyModels = " + fProxyModels);
}
+ if ( (flags & STATE_UPDATES) != 0) {
+ buf.append("\n\t");
+ buf.append("fStateUpdates = " + toString(fStateUpdates));
+ }
if (fTimeoutInterval > 0) {
buf.append("\n\t");
buf.append("fTimeoutInterval = " + fTimeoutInterval);
@@ -636,7 +716,7 @@ public class TestModelUpdatesListener
}
public String toString() {
- return toString(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE | STATE_RESTORE_COMPLETE | VIEWER_UPDATES_STARTED | LABEL_UPDATES_STARTED);
+ return toString(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE | STATE_RESTORE_COMPLETE | VIEWER_UPDATES_STARTED | LABEL_UPDATES_STARTED | STATE_UPDATES);
}
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java
index f856855e0..882a7df4e 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java
@@ -23,7 +23,7 @@ import org.eclipse.ui.progress.UIJob;
/**
* @since 3.3
*/
-class ElementCompareRequest extends MementoUpdate implements IElementCompareRequest {
+public class ElementCompareRequest extends MementoUpdate implements IElementCompareRequest {
private boolean fEqual;
private final int fModelIndex;
@@ -74,7 +74,7 @@ class ElementCompareRequest extends MementoUpdate implements IElementCompareRequ
job.schedule();
}
- boolean isEqual() {
+ public boolean isEqual() {
return fEqual;
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ITreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ITreeModelContentProvider.java
index 1bbb00b53..e4d5f3dc3 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ITreeModelContentProvider.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ITreeModelContentProvider.java
@@ -17,6 +17,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateList
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.jface.viewers.ILazyTreePathContentProvider;
import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.Viewer;
/**
* {@link TreeModelViewer} content provider interface.
@@ -192,4 +193,16 @@ public interface ITreeModelContentProvider extends ILazyTreePathContentProvider
* @param flags Flags indicating the changes to cancel.
*/
public void cancelRestore(TreePath path, int flags);
+
+ /**
+ * Notifies the content provider that a client called {@link Viewer#setInput(Object)},
+ * and the viewer input is about to change.
+ *
+ * @param viewer The viewer that uses this content provider.
+ * @param oldInput Old input object.
+ * @param newInput New input object.
+ *
+ * @since 3.7
+ */
+ public void inputAboutToChange(ITreeModelContentProviderTarget viewer, Object oldInput, Object newInput);
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java
index b342febde..5fd9cf229 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java
@@ -1217,10 +1217,23 @@ public class InternalTreeModelViewer extends TreeViewer
return super.hasFilters();
}
+ protected void unmapAllElements() {
+ // Do nothing when called from StructuredViewer.setInput(), to avoid
+ // clearing elements before viewer state is saved.
+ // Bug 326917
+ if (getControl().isDisposed()) {
+ unmapAllElements();
+ }
+ }
+
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.AbstractTreeViewer#inputChanged(java.lang.Object, java.lang.Object)
*/
protected void inputChanged(Object input, Object oldInput) {
+ ((ITreeModelContentProvider)getContentProvider()).inputAboutToChange(this, oldInput, input);
+ // Clear items map now that we've called inputAboutToChange.
+ // Bug 326917
+ super.unmapAllElements();
super.inputChanged(input, oldInput);
resetColumns(input);
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java
index dff4d630c..b33650bca 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalVirtualTreeModelViewer.java
@@ -208,6 +208,8 @@ public class InternalVirtualTreeModelViewer extends Viewer
public void setInput(Object input) {
Object oldInput = fInput;
+ getContentProvider().inputAboutToChange(this, oldInput , input);
+ fItemsMap.clear();
getContentProvider().inputChanged(this, oldInput, input);
fInput = input;
fTree.setData(fInput);
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java
index 4aeebd1b7..056734da1 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java
@@ -25,8 +25,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
@@ -316,6 +316,16 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi
return fViewer == null;
}
+ public synchronized void inputAboutToChange(ITreeModelContentProviderTarget viewer, Object oldInput, Object newInput) {
+ if (newInput != oldInput && oldInput != null) {
+ for (Iterator itr = fCompareRequestsInProgress.values().iterator(); itr.hasNext();) {
+ ((ElementCompareRequest) itr.next()).cancel();
+ itr.remove();
+ }
+ saveViewerState(oldInput);
+ }
+ }
+
/*
* (non-Javadoc)
*
@@ -325,13 +335,6 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi
*/
public synchronized void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
fViewer = (ITreeModelContentProviderTarget) viewer;
- if (oldInput != null) {
- for (Iterator itr = fCompareRequestsInProgress.values().iterator(); itr.hasNext();) {
- ((ElementCompareRequest) itr.next()).cancel();
- itr.remove();
- }
- saveViewerState(oldInput);
- }
if (newInput != oldInput) {
cancelSubtreeUpdates(TreePath.EMPTY);
disposeAllModelProxies();
@@ -2243,5 +2246,4 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi
}
}
}
-
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/SubTreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/SubTreeModelViewer.java
index 486d89f64..6d46f29a2 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/SubTreeModelViewer.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/SubTreeModelViewer.java
@@ -466,6 +466,10 @@ public class SubTreeModelViewer extends TreeModelViewer {
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
fBaseProvider.inputChanged(fDelegatingViewer, oldInput, newInput);
}
+
+ public void inputAboutToChange(ITreeModelContentProviderTarget viewer, Object oldInput, Object newInput) {
+ fBaseProvider.inputAboutToChange(viewer, oldInput, newInput);
+ }
}
/**
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java
index f8d10a49a..8797b4a11 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java
@@ -443,24 +443,22 @@ public class TreeModelContentProvider extends ModelContentProvider implements IT
// Add memento for top item if it is mapped to an element. The reveal memento
// is in its own path to avoid requesting unnecessary data when restoring it.
- if (viewer.getInput() != null) {
- TreePath topElementPath = viewer.getTopElementPath();
- if (topElementPath != null) {
- ModelDelta parentDelta = delta;
- TreePath parentPath = EMPTY_TREE_PATH;
- for (int i = 0; i < topElementPath.getSegmentCount(); i++) {
- Object element = topElementPath.getSegment(i);
- int index = viewer.findElementIndex(parentPath, element);
- ModelDelta childDelta = parentDelta.getChildDelta(element);
- if (childDelta == null) {
- parentDelta = parentDelta.addNode(element, index, IModelDelta.NO_CHANGE);
- } else {
- parentDelta = childDelta;
- }
- parentPath = parentPath.createChildPath(element);
- }
- parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.REVEAL);
- }
+ TreePath topElementPath = viewer.getTopElementPath();
+ if (topElementPath != null) {
+ ModelDelta parentDelta = delta;
+ TreePath parentPath = EMPTY_TREE_PATH;
+ for (int i = 0; i < topElementPath.getSegmentCount(); i++) {
+ Object element = topElementPath.getSegment(i);
+ int index = viewer.findElementIndex(parentPath, element);
+ ModelDelta childDelta = parentDelta.getChildDelta(element);
+ if (childDelta == null) {
+ parentDelta = parentDelta.addNode(element, index, IModelDelta.NO_CHANGE);
+ } else {
+ parentDelta = childDelta;
+ }
+ parentPath = parentPath.createChildPath(element);
+ }
+ parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.REVEAL);
}
}

Back to the top