public static bool Add( TREENODE parentNode, PositionTracker[] positions, int positionIndex, int relativeRow, int relativeColumn, ref NODEPOSITIONTRACKER lastTracker) { Debug.Assert((lastTracker == null) || (lastTracker.myNext == null)); Debug.Assert(!parentNode.NoTracking); var retVal = false; NODEPOSITIONTRACKER newTracker = null; if (parentNode.DefaultTracking) { newTracker = new NODEPOSITIONTRACKER_Default(parentNode, positions, positionIndex, relativeRow, relativeColumn); } else { object trackerObject; var dummyOptions = 0; trackerObject = parentNode.Branch.GetObject(relativeRow, relativeColumn, ObjectStyle.TrackingObject, ref dummyOptions); if (trackerObject != null) { newTracker = new NODEPOSITIONTRACKER_Dynamic(parentNode, positions, positionIndex, trackerObject); } } if (newTracker != null) { if (lastTracker != null) { lastTracker.myNext = newTracker; } lastTracker = newTracker; retVal = true; } return retVal; }
public static void DetachAll(ref NODEPOSITIONTRACKER ntHead) { var ntCur = ntHead; ntHead = null; while (ntCur != null) { if (ntCur.myParentNode != null) { // Note that this will detach multiple nodes. The sibling // chains don't matter as long as they aren't attached to any TREENODE. ntCur.myParentNode.FirstPositionTracker = null; } ntCur = ntCur.myNext; } }
private void DoBeforeListShuffle() { DelayTurnOffRedraw(); // Begin shuffling list by retrieving PositionTracker arrays from // all of our listeners (if any). Debug.Assert(myPositionManager == null); // Should be long gone at this point // Check after as well, Before is useless without an After listener if (ListShuffleBeginning != null && ListShuffleEnding != null) { var positionManager = new PositionManagerEventArgs(this); NODEPOSITIONTRACKER ntHead = null; NODEPOSITIONTRACKER ntLast = null; TREENODE tnParent; int relativeRow; int relativeColumn; try { ListShuffleBeginning(this, positionManager); foreach (PositionTracker[] trackerSet in positionManager) { var upper = trackerSet.GetUpperBound(0); for (var i = trackerSet.GetLowerBound(0); i <= upper; ++i) { if (TrackPosition(ref trackerSet[i], out tnParent, out relativeRow, out relativeColumn)) { if (ntHead != null) { if (NODEPOSITIONTRACKER.Add(tnParent, trackerSet, i, relativeRow, relativeColumn, ref ntLast)) { continue; } } else if (NODEPOSITIONTRACKER.Add(tnParent, trackerSet, i, relativeRow, relativeColumn, ref ntHead)) { ntLast = ntHead; continue; } } ClearPositionTracker(ref trackerSet[i]); } } } catch { // Errors from the branches are caught during add, so this is a // failure on our side. Make sure that all position tracking information // is fully detached from the TREENODE objects before continuing. if (ntHead != null) { NODEPOSITIONTRACKER.DetachAll(ref ntHead); } throw; } finally { // We made it all the way, go ahead and record the results // with this object. Note that we record our results even if // the position head is null so that the user gets a ListShuffleEnding // event if nothing was tracked successfully. This lets the listener // reduce the set of operations they do during other insert and delete // notifications while a position manager is active. myPositionManager = positionManager; myPositionHead = ntHead; } } }
public static void DetachTrackers(ref NODEPOSITIONTRACKER ntFirst, ref NODEPOSITIONTRACKER_Dynamic ntDetached) { Debug.Assert(ntFirst != null); // Precondition, check before calling var ntHead = (NODEPOSITIONTRACKER_Dynamic)ntFirst; var ntNext = ntHead; NODEPOSITIONTRACKER_Dynamic ntCur = null; while (ntNext != null) { ntCur = ntNext; ntCur.myParentNode = null; ntNext = (NODEPOSITIONTRACKER_Dynamic)ntCur.myNextSibling; } // Link all of the detached objects together ntCur.myNextSibling = ntDetached; ntDetached = ntHead; ntFirst = null; }
public static void UpdateParentNode(NODEPOSITIONTRACKER ntHead, TREENODE newParentNode) { var ntCur = ntHead; while (ntCur != null) { ntCur.myParentNode = newParentNode; ntCur = ntCur.myNextSibling; } }
public static void UpdateEndPositions(NODEPOSITIONTRACKER ntHead) { var ntCur = ntHead; while (ntCur != null) { ntCur.UpdateEndPosition(ref ntCur.myPositions[ntCur.myPositionIndex]); ntCur = ntCur.myNext; } }
public void TransferPositionTrackerTo(TREENODE tn) { if (FirstPositionTracker == null) { return; } Debug.Assert(tn.FirstPositionTracker == null); tn.FirstPositionTracker = FirstPositionTracker; FirstPositionTracker = null; NODEPOSITIONTRACKER.UpdateParentNode(tn.FirstPositionTracker, tn); }