Example #1
0
        /// <summary>
        /// Applies the changes to the project, and updates the display.
        ///
        /// This is called by the undo/redo commands.  Don't call this directly from the
        /// various UI-driven functions, as this does not add the change to the undo stack.
        /// </summary>
        /// <param name="cs">Set of changes to apply.</param>
        /// <param name="backward">If set, undo the changes instead.</param>
        private void ApplyChanges(ChangeSet cs, bool backward)
        {
            mReanalysisTimer.Clear();
            mReanalysisTimer.StartTask("ProjectView.ApplyChanges()");

            mReanalysisTimer.StartTask("Save selection");
#if false
            int topItem = codeListView.TopItem.Index;
#else
            int topItem = 0;
#endif
            int topOffset = mDisplayList[topItem].FileOffset;
            DisplayListGen.SavedSelection savedSel = DisplayListGen.SavedSelection.Generate(
                mDisplayList, mCodeViewSelection, topOffset);
            //savedSel.DebugDump();
            mReanalysisTimer.EndTask("Save selection");

            mReanalysisTimer.StartTask("Apply changes");
            UndoableChange.ReanalysisScope needReanalysis = mProject.ApplyChanges(cs, backward,
                                                                                  out RangeSet affectedOffsets);
            mReanalysisTimer.EndTask("Apply changes");

            string refreshTaskStr = "Refresh w/reanalysis=" + needReanalysis;
            mReanalysisTimer.StartTask(refreshTaskStr);
            if (needReanalysis != UndoableChange.ReanalysisScope.None)
            {
                Debug.WriteLine("Refreshing project (" + needReanalysis + ")");
                RefreshProject(needReanalysis);
            }
            else
            {
                Debug.WriteLine("Refreshing " + affectedOffsets.Count + " offsets");
                RefreshCodeListViewEntries(affectedOffsets);
                mProject.Validate();    // shouldn't matter w/o reanalysis, but do it anyway
            }
            mReanalysisTimer.EndTask(refreshTaskStr);

            VirtualListViewSelection newSel = savedSel.Restore(mDisplayList, out int topIndex);
            //newSel.DebugDump();

            // Refresh the various windows, and restore the selection.
            mReanalysisTimer.StartTask("Invalidate controls");
#if false
            InvalidateControls(newSel);
#endif
            mReanalysisTimer.EndTask("Invalidate controls");

            // This apparently has to be done after the EndUpdate, and inside try/catch.
            // See https://stackoverflow.com/questions/626315/ for notes.
            try {
                Debug.WriteLine("Setting TopItem to index=" + topIndex);
#if false
                codeListView.TopItem = codeListView.Items[topIndex];
#endif
            } catch (NullReferenceException) {
                Debug.WriteLine("Caught an NRE from TopItem");
            }

            mReanalysisTimer.EndTask("ProjectView.ApplyChanges()");

            //mReanalysisTimer.DumpTimes("ProjectView timers:", mGenerationLog);
#if false
            if (mShowAnalysisTimersDialog != null)
            {
                string timerStr = mReanalysisTimer.DumpToString("ProjectView timers:");
                mShowAnalysisTimersDialog.BodyText = timerStr;
            }
#endif

            // Lines may have moved around.  Update the selection highlight.  It's important
            // we do it here, and not down in DoRefreshProject(), because at that point the
            // ListView's selection index could be referencing a line off the end.
#if false
            UpdateSelectionHighlight();
#endif
        }