diff options
author | Pawel Piech | 2011-02-17 23:35:05 +0000 |
---|---|---|
committer | Pawel Piech | 2011-02-17 23:35:05 +0000 |
commit | 72e7c4b13aae82485317cdc200763ffed545651a (patch) | |
tree | f0b19eaa24c62048bfd816102c073d43690c39bf | |
parent | ff93e1ff431ec06321bce8f1e612dd925b2af009 (diff) | |
download | eclipse.platform.debug-72e7c4b13aae82485317cdc200763ffed545651a.tar.gz eclipse.platform.debug-72e7c4b13aae82485317cdc200763ffed545651a.tar.xz eclipse.platform.debug-72e7c4b13aae82485317cdc200763ffed545651a.zip |
Bug 335193 - NullPointerException raised by ModelContentProvider.cancelRestore
-rw-r--r-- | org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java | 74 | ||||
-rw-r--r-- | org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java | 54 |
2 files changed, 113 insertions, 15 deletions
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 2092f6605..d400f3a45 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 @@ -54,7 +54,9 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi protected void setUp() throws Exception { fDisplay = PlatformUI.getWorkbench().getDisplay(); fShell = new Shell(fDisplay, SWT.ON_TOP | SWT.SHELL_TRIM); - fShell.setMaximized(true); + // Maximizing a shell with SWT.ON_TOP doesn't work on Linux (bug 325465) + //fShell.setMaximized(true); + fShell.setSize(800, 600); fShell.setLayout(new FillLayout()); fViewer = createViewer(fDisplay, fShell); @@ -936,4 +938,74 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("6")) == false); Assert.assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); } + + public void testPreserveCollapseAndSelectDeltaAfterSaveAndRestore() { + //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); + TestModel model = TestModel.simpleMultiLevel(); + + // Expand all + fViewer.setAutoExpandLevel(-1); + + // Create the listener. + fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, 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); + + fViewer.setSelection(new TreeSelection(model.findElement("3"))); + + // Turn off auto-expand + fViewer.setAutoExpandLevel(0); + + // Set the viewer input to null. This will trigger the view to save the viewer state. + fListener.reset(false, false); + fViewer.setInput(null); + while (!fListener.isFinished(STATE_SAVE_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Set the viewer input back to the model. When view updates are complete + // the viewer + // Note: disable redundant updates because the reveal delta triggers one. + fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); + fViewer.setInput(model.getRootElement()); + TreePath path = model.findElement("2"); + fListener.addUpdates(null, path, (TestElement)path.getLastSegment(), 0, STATE_UPDATES); + path = model.findElement("3"); + fListener.addUpdates(null, path, (TestElement)path.getLastSegment(), 0, STATE_UPDATES); + + // Wait till we restore state of elements we want to collapse and select + while (!fListener.isFinished(STATE_RESTORE_STARTED | STATE_UPDATES | CHILDREN_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Update the viewer to collapse both elements and select a third + ModelDelta delta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); + + // Post first collapse delta + model.postDelta(model.makeElementDelta(model.findElement("2"), IModelDelta.COLLAPSE)); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Post second collapse delta + fListener.resetModelChanged(); + model.postDelta(model.makeElementDelta(model.findElement("3"), IModelDelta.COLLAPSE)); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Post select delta + model.postDelta(model.makeElementDelta(model.findElement("1"), IModelDelta.SELECT)); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Wait for all the updates to complete (note: we're not resetting the listener). + while (!fListener.isFinished(STATE_RESTORE_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Check to make sure that the state restore didn't change the selection. + Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("2")) == false); + Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == false); + Assert.assertEquals(new TreeSelection(model.findElement("1")), fViewer.getSelection()); + } + } 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 056734da1..8ba366695 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 IBM Corporation and others. + * Copyright (c) 2006, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -499,25 +499,26 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi boolean checkChildrenRealized); public void cancelRestore(final TreePath path, final int flags) { - if (fPendingState == null && fPendingSetTopItem == null) { - // Nothing to do - return; - } - if (fInStateRestore) { // If we are currently processing pending state already, ignore // cancelRestore requests. These requests may be triggered in the viewer // by changes to the tree state (Bug 295585). return; } + + if ((flags & IModelDelta.REVEAL) != 0 && fPendingSetTopItem != null) { + fPendingSetTopItem.dispose(); + return; + } + + // Nothing else to do + if (fPendingState == null) { + return; + } if ((flags & (IModelDelta.SELECT | IModelDelta.REVEAL)) != 0) { // If we're canceling reveal and this is waiting for updates to complete // then just cancel it and return - if ((flags & IModelDelta.REVEAL) != 0 && fPendingSetTopItem != null) { - fPendingSetTopItem.dispose(); - return; - } // If we're canceling select or reveal, cancel it for all of pending deltas final int mask = flags & (IModelDelta.SELECT | IModelDelta.REVEAL); @@ -540,7 +541,16 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi // For other flags (EXPAND/COLLAPSE), cancel only from the matching path. fPendingState.accept(new IModelDeltaVisitor() { public boolean visit(IModelDelta delta, int depth) { - if (depth == path.getSegmentCount()) { + if (depth < path.getSegmentCount()) { + // Descend until we reach a matching depth. + TreePath deltaPath = getViewerTreePath(delta); + if (path.startsWith(deltaPath, null)) { + return true; + } else { + return false; + } + } + else if (depth == path.getSegmentCount()) { TreePath deltaPath = getViewerTreePath(delta); if (deltaPath.equals(path)) { int deltaFlags = delta.getFlags(); @@ -551,10 +561,24 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi } } ((ModelDelta)delta).setFlags(newFlags); - } + if ((flags & IModelDelta.EXPAND) != 0) { + // Descend delta to clear the EXPAND flags of a canceled expand + return true; + } + } return false; - } - return true; + } else { + // We're clearing out flags of a matching sub-tree + // assert (flags & IModelDelta.EXPAND) != 0; + + if (DEBUG_STATE_SAVE_RESTORE && DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + if (delta.getFlags() != IModelDelta.NO_CHANGE) { + System.out.println("\tCANCEL: " + delta.getElement() + "(" + Integer.toHexString(delta.getFlags()) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + ((ModelDelta)delta).setFlags(IModelDelta.NO_CHANGE); + return true; + } } }); } @@ -1388,6 +1412,8 @@ abstract class ModelContentProvider implements IContentProvider, IModelChangedLi updateNodes(deltaArray, mask & ITreeModelContentProvider.UPDATE_MODEL_DELTA_FLAGS & ~(IModelDelta.REMOVED | IModelDelta.UNINSTALL)); updateNodes(deltaArray, mask & ITreeModelContentProvider.CONTROL_MODEL_DELTA_FLAGS); + + checkIfRestoreComplete(); } /** |