/// <summary> /// Loads a document into display TreeViews, updates the cache, and /// rebuilds the file manager that represents the document. /// </summary> /// <param name="d">The Document to load.</param> /// <param name="tw">The tool window associated with the cache.</param> /// <remarks> /// If the document is in the cache, it is reused. /// </remarks> public void AddDocumentToCache(Document d, SourceOutlineToolWindow tw) { Debug.Assert(d != null); _toolWindow = tw; if (d == _document) { return; } if (_document != null) { // Unregister events for the previous document. tw.UnRegisterTreeEvents(fileManager.TreeView, fileManager.FilterView); control.RemoveTreeFromControls(fileManager.TreeView); control.RemoveTreeFromControls(fileManager.FilterView); } _document = d; fileManager = new CodeOutlineFileManager(control, dte, d, tw, languageService); tw.RegisterTreeEvents(fileManager.TreeView, fileManager.FilterView); // Load the control. control.AddTreeToControls(fileManager.TreeView); control.AddTreeToControls(fileManager.FilterView); fileManager.State = CodeOutlineFileManager.OutlineFileManagerState.StartLoadingCodeModel; fileManager.HideTrees(); control.HideTrees(); control.TreeView = fileManager.TreeView; control.FilterView = fileManager.FilterView; // Re-display the last CodeElementType selected for this document. tw.SelectedType = fileManager.ElementFilter; // Re-display the last filter text entered for this document, but only if the file is loaded. if (fileManager.State == CodeOutlineFileManager.OutlineFileManagerState.DoneLoadingCodeModel) { fileManager.ReApplyText(); tw.SelectedFilterText = fileManager.FilterText; } else { control.Reset(); } }
/// <summary> /// Called when the Visual Studio IDE goes idle to give /// the component a chance to perform idle time tasks. /// </summary> /// <param name="grfidlef"> /// A group of bit flags taken from the enumeration of oleidlef values, /// indicating the type of idle tasks to perform. /// </param> /// <returns> /// TRUE (not zero) if more time is needed to perform the idle time tasks, otherwise FALSE (zero). /// </returns> /// <remarks> /// The component may periodically call FContinueIdle and, if it returns /// false, the component should terminate its idle time processing and return. /// If a component reaches a point where it has no idle tasks and does not need /// FDoIdle calls, it should remove its idle task registration via /// FUpdateComponentRegistration. If this method is called while the component /// is performing a tracking operation, the component should only perform idle time /// tasks that it deems appropriate to perform during tracking. /// </remarks> public int FDoIdle(uint grfidlef) { var tickCount = (uint)Environment.TickCount; if (tickCount < lastTickCount) { // The tick count rolled over, so treat this as if the timeout has expired // to keep from waiting until the count gets up to the required value again. } else { // Check to see when the last occurrence was. Only search once per second. if ((tickCount - lastTickCount) < delayBetweenIdleProcessing) { return(0); } } // added by Xizhi, we will prevent DomCode parsing when outliner is not visible. if (((IVsWindowFrame)this.Frame).IsVisible() != VSConstants.S_OK) { return(0); } try { if (codeCache.CurrentFileManager != null) { CodeOutlineFileManager.OutlineFileManagerState state = codeCache.CurrentFileManager.State; switch (state) { case CodeOutlineFileManager.OutlineFileManagerState.StartLoadingCodeModel: // Load completely anew. control.ShowWaitWhileReadyMessage(); codeCache.CurrentFileManager.Load(); return(0); case CodeOutlineFileManager.OutlineFileManagerState.LoadingCodeModel: // Continue loading after an interruption. codeCache.CurrentFileManager.ContinueLoading(); return(0); case CodeOutlineFileManager.OutlineFileManagerState.DoneLoadingCodeModel: // Loading is complete. codeCache.CurrentFileManager.FinishLoading(); codeCache.CurrentFileManager.TreeView.Refresh(); codeCache.CurrentFileManager.FilterView.Refresh(); control.Enabled = codeCache.CurrentFileManager.FileIsOutlined; if (control.Enabled) { var selectedType = (CodeElementType)Enum.Parse(typeof(CodeElementType), control. filterToolStripCombo. SelectedItem.ToString()); codeCache.CurrentFileManager.ElementFilter = selectedType; } control.HideWaitWhileReadyMessage(); control.Reset(); codeCache.CurrentFileManager.State = CodeOutlineFileManager.OutlineFileManagerState.WaitToStartOver; return(0); case CodeOutlineFileManager.OutlineFileManagerState.WaitToStartOver: break; } } // Get the current active TextPoint from the DTE. if ((dte.ActiveDocument == null) || (codeCache == null) || (codeCache.CurrentFileManager == null) || (codeCache.CurrentFileManager.TreeViewFocused) || !control.Enabled) { return(0); } var sel = (TextSelection)dte.ActiveDocument.Selection; if (sel == null) { return(0); } var tp = (TextPoint)sel.ActivePoint; if ((tp.Line == lineNum) && (tp.LineCharOffset == colNum)) { if (!codeElementSelectedOnIdle && ((tickCount - lastTickCountBeforeUpdate) > delayBetweenCodeElementSelection)) { codeElementSelectedOnIdle = true; // Turn off pretty listing to fix the problem with line autocompletion // being invoked when the code element position is determined. Properties properties = null; try { properties = dte.get_Properties("TextEditor", "Basic-Specific"); } catch { } Property property = null; if (properties != null) { foreach (Property p in properties) { if (p.Name == "PrettyListing") { property = p; break; } } } var currentPrettyListing = true; if (property != null) { currentPrettyListing = (bool)property.Value; property.Value = false; } codeCache.CurrentFileManager.SelectCodeElement(tp); // Set pretty listing back to its previous value. if (property != null) { property.Value = currentPrettyListing; } lastTickCountBeforeUpdate = tickCount; } } else { codeElementSelectedOnIdle = false; } lineNum = tp.Line; colNum = tp.LineCharOffset; } catch (Exception ex) { DisplayMessage(Resources.ErrorPrefix, "FDoIdle exception: " + ex); } lastTickCount = tickCount; return(0); }